如何将安装程序复制到临时文件,然后 运行 它?
How can I copy the installer to the temp file and then run it?
我正在尝试将安装程序复制到临时文件夹,然后从该位置 运行 复制它。
这就是我想要做的,但到目前为止无济于事。
FileCopy(ExpandConstant('{srcexe}'), ExpandConstant('{tmp}\Setup.exe'), True);
Exec(ExpandConstant('{tmp}\Setup.exe'), '', '', SW_SHOW, ewWaitUntilTerminated, ResultCode)
如何将安装程序复制到临时文件,然后从代码部分运行复制它?
不知道为什么,但是有一个明确的检查可以防止 FileCopy
function 复制安装程序本身。
看到一个PathCompare
check in FileCopy
branch of CmnFunc2Proc
in ScriptFunc_R.pas
:
end else if Proc.Name = 'FILECOPY' then begin
ExistingFilename := Stack.GetString(PStart-1);
if PathCompare(ExistingFilename, SetupLdrOriginalFilename) <> 0 then
Stack.SetBool(PStart, CopyFileRedir(ScriptFuncDisableFsRedir,
ExistingFilename, Stack.GetString(PStart-2), Stack.GetBool(PStart-3)))
else
Stack.SetBool(PStart, False);
我不知道这是什么原因,但可能有一些。所以当心,你可能正在做一些安装程序不喜欢的事情。
你当然可以通过调用 Windows copy
command:
来解决这个问题
Exec(
ExpandConstant('{cmd}'),
Format('/C copy "%s" "%s"', [ExpandConstant('{srcexe}'), ExpandConstant('{tmp}\Setup.exe')]),
'', SW_HIDE, ewWaitUntilTerminated, ResultCode);
或者您可以使用 TFileStream
class:
实现替换功能
function FileCopyUnrestricted(const ExistingFile, NewFile: String): Boolean;
var
Buffer: string;
Stream: TFileStream;
Size: Integer;
begin
Result := True;
try
Stream := TFileStream.Create(ExistingFile, fmOpenRead or fmShareDenyNone);
try
Size := Stream.Size;
SetLength(Buffer, Size div 2 + 1);
Stream.ReadBuffer(Buffer, Size);
finally
Stream.Free;
end;
except
Result := False;
end;
if Result then
begin
try
Stream := TFileStream.Create(NewFile, fmCreate);
try
Stream.WriteBuffer(Buffer, Size);
finally
Stream.Free;
end;
except
Result := False;
end;
end;
end;
这是将整个文件加载到内存的低效实现。如果您的安装程序很大,您将不得不改进代码以分块复制文件。
该代码适用于 Inno Setup 的 Unicode 版本(Inno Setup 6 的唯一版本)。
我正在尝试将安装程序复制到临时文件夹,然后从该位置 运行 复制它。
这就是我想要做的,但到目前为止无济于事。
FileCopy(ExpandConstant('{srcexe}'), ExpandConstant('{tmp}\Setup.exe'), True);
Exec(ExpandConstant('{tmp}\Setup.exe'), '', '', SW_SHOW, ewWaitUntilTerminated, ResultCode)
如何将安装程序复制到临时文件,然后从代码部分运行复制它?
不知道为什么,但是有一个明确的检查可以防止 FileCopy
function 复制安装程序本身。
看到一个PathCompare
check in FileCopy
branch of CmnFunc2Proc
in ScriptFunc_R.pas
:
end else if Proc.Name = 'FILECOPY' then begin
ExistingFilename := Stack.GetString(PStart-1);
if PathCompare(ExistingFilename, SetupLdrOriginalFilename) <> 0 then
Stack.SetBool(PStart, CopyFileRedir(ScriptFuncDisableFsRedir,
ExistingFilename, Stack.GetString(PStart-2), Stack.GetBool(PStart-3)))
else
Stack.SetBool(PStart, False);
我不知道这是什么原因,但可能有一些。所以当心,你可能正在做一些安装程序不喜欢的事情。
你当然可以通过调用 Windows copy
command:
Exec(
ExpandConstant('{cmd}'),
Format('/C copy "%s" "%s"', [ExpandConstant('{srcexe}'), ExpandConstant('{tmp}\Setup.exe')]),
'', SW_HIDE, ewWaitUntilTerminated, ResultCode);
或者您可以使用 TFileStream
class:
function FileCopyUnrestricted(const ExistingFile, NewFile: String): Boolean;
var
Buffer: string;
Stream: TFileStream;
Size: Integer;
begin
Result := True;
try
Stream := TFileStream.Create(ExistingFile, fmOpenRead or fmShareDenyNone);
try
Size := Stream.Size;
SetLength(Buffer, Size div 2 + 1);
Stream.ReadBuffer(Buffer, Size);
finally
Stream.Free;
end;
except
Result := False;
end;
if Result then
begin
try
Stream := TFileStream.Create(NewFile, fmCreate);
try
Stream.WriteBuffer(Buffer, Size);
finally
Stream.Free;
end;
except
Result := False;
end;
end;
end;
这是将整个文件加载到内存的低效实现。如果您的安装程序很大,您将不得不改进代码以分块复制文件。
该代码适用于 Inno Setup 的 Unicode 版本(Inno Setup 6 的唯一版本)。