调试自动生成的Inno Setup安装程序 [英] Debugging Inno Setup installer that respawns itself
问题描述
从此问题可以看出,我们开始了Inno Setup的新实例:
As it can be seen from this question we start a new instance of Inno Setup:
Instance := ShellExecute(0, '', ExpandConstant('{srcexe}'), Params, '', SW_SHOW);
其中
function ShellExecute(hwnd: HWND; lpOperation: string; lpFile: string;
lpParameters: string; lpDirectory: string; nShowCmd: Integer): THandle;
external 'ShellExecuteW@shell32.dll stdcall';
来自此问题的答案的所有代码,我移到了 VCL_Styles.iss
文件,并将其包含在我的主脚本中.
All the code from this question's answer I moved to the VCL_Styles.iss
file and included it into my main script.
问题是我通过了 ShellExecute
调用并由调试器终止后,一个Inno Setup实例继续运行(因此我必须使用Windows Task Manager终止该进程),然后我在 Debug Output
(调试输出)中获得以下消息:
The problem is that after I've passed the ShellExecute
call and terminate by the debugger afterwards one instance of Inno Setup keeps running (so I have to kill the process using Windows Task Manager) and I get the following messages in the Debug Output
:
***终止过程
*** Terminating process
***删除剩余的临时目录:C:\ Users \ JCONST〜1 \ AppData \ Local \ Temp \ is-PV9OS.tmp
*** Removing left-over temporary directory: C:\Users\JCONST~1\AppData\Local\Temp\is-PV9OS.tmp
***安装程序仍在运行;无法获取退出代码
*** Setup is still running; can't get exit code
代替退出代码6,该退出代码会在文档时返回:
instead of exit code 6 which according to the documentation is returned when:
调试程序强行终止了安装过程(运行|在Compiler IDE中使用了Terminate.)
The Setup process was forcefully terminated by the debugger (Run | Terminate was used in the Compiler IDE).
我不确定Inno Setup的哪个实例仍在运行,如何停止它?
I'm not sure which instance of Inno Setup is still running and how can I stop it?
以下是我包含在主脚本中的 VCL.Styles
的内容,因此出现了上述错误:
Here's the contents of the VCL.Styles
that I include into my main script so I get the aforementioned error:
[Setup]
ShowLanguageDialog=no
[Code]
function ShellExecute(hwnd: HWND; lpOperation: string; lpFile: string;
lpParameters: string; lpDirectory: string; nShowCmd: Integer): THandle;
external 'ShellExecuteW@shell32.dll stdcall';
<event('InitializeSetup')>
function MyInitializeSetup2: Boolean;
var
Instance: THandle;
I: Integer;
S, Params, Language: String;
begin
Result := True;
for I := 1 to ParamCount do
begin
S := ParamStr(I);
if CompareText(Copy(S, 1, 5), '/SL5=') <> 0 then
begin
Params := Params + AddQuotes(S) + ' ';
end;
end;
Params := Params + '/LANG=en';
Language := ExpandConstant('{param:LANG}');
if Language = '' then
begin
Instance := ShellExecute(0, '', ExpandConstant('{srcexe}'), Params, '', SW_SHOW);
if Instance <= 32 then
begin
S := 'Running installer with the selected language failed. Code: %d';
MsgBox(Format(S, [Instance]), mbError, MB_OK);
end;
Result := False;
Exit;
end;
end;
推荐答案
当调试器遍历 ShellExecute
并启动安装程序进程的新实例时,IDE调试器似乎选择了该进程.并重新启动调试.我认为这不是故意的行为,或者至少不是经过充分测试的行为.然后, Terminate 函数可能试图关闭/与旧进程通信(与此同时,旧进程本身已终止-由于其 InitializeSetup
返回 False
在 ShellExecute
之后).
When the debugger steps over the ShellExecute
and the new instance of the installer process is started, the IDE debugger seems to pick that process and restarts the debugging. I assume this is not intended behaviour, or at least not a well-tested one. The Terminate function then probably tries to close/communicate with to the old process (which has terminated on its own meanwhile – due to its InitializeSetup
returning False
after the ShellExecute
).
Martijn Laan(Inno Setup的当前维护者)表示,Inno Setup并非旨在自行产生.实际上,Inno Setup自己的 Exec
API明确禁止重新生成安装程序.通过使用WinAPI ShellExecute
绕过此限制,而是引入了问题中描述的问题.调试器无法处理这种情况也就不足为奇了.
Martijn Laan (the current maintainer of Inno Setup) stated that Inno Setup is not designed to respawn itself. Actually Inno Setup own Exec
API explicitly prevents respawning the installer. Bypassing this restriction by using WinAPI ShellExecute
instead introduces the problem described in the question. It's not a surprise that the debugger cannot handle this situation.
这篇关于调试自动生成的Inno Setup安装程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!