Inno Setup:点击Finish后使软件exe置于网页顶层的问题
解决方案:让ABC.exe启动后处于顶层
要解决点击Finish按钮后网页始终在ABC.exe顶层的问题,我们可以通过调整启动顺序+设置窗口置顶的方式实现,或者在安装程序退出前主动将ABC.exe窗口置顶。以下是具体实现方案:
方案1:调整启动顺序并主动置顶(推荐)
该方案将ABC.exe和网页的启动逻辑统一放到代码段中,先启动ABC.exe并等待其窗口加载完成,设置窗口置顶后再启动网页,确保ABC.exe始终处于顶层。
步骤1:替换原Run段为自定义任务
首先删除原Run段配置,在脚本中添加自定义任务(保留用户是否启动ABC的可选性):
[Tasks] Name: launchabc; Description: {cm:LaunchProgram,ABC}; GroupDescription: {cm:AdditionalTasks}; Flags: unchecked
步骤2:修改代码段逻辑
更新[Code]段内容,实现先启动ABC.exe并置顶,再启动网页:
const insSiteURLEN = 'https://example.com'; // Windows API常量 HWND_TOPMOST = -1; SWP_NOMOVE = $0002; SWP_NOSIZE = $0001; // 引入Windows API函数 procedure SetWindowPos(hWnd: HWND; hWndInsertAfter: HWND; X, Y, cx, cy: Integer; uFlags: UINT); external 'SetWindowPos@user32.dll stdcall'; function FindWindow(lpClassName, lpWindowName: PChar): HWND; external 'FindWindowA@user32.dll stdcall'; // 等待目标窗口出现,超时返回0 function WaitForWindow(const WindowTitle: string; Timeout: Integer): HWND; var StartTime: DWORD; begin Result := 0; StartTime := GetTickCount; while (GetTickCount - StartTime < Timeout) do begin // 替换为ABC.exe实际的窗口标题 Result := FindWindow(nil, PChar('ABC窗口标题')); if Result <> 0 then Break; Sleep(100); end; end; procedure CurStepChanged(CurStep: TSetupStep); var ErrorCode: Integer; ExeHWND: HWND; begin if CurStep = ssDone then begin // 检查用户是否勾选启动ABC if IsTaskSelected('launchabc') then begin // 启动ABC.exe(最大化显示) ShellExec('', ExpandConstant('{app}\abc.exe'), '', ExpandConstant('{app}'), SW_SHOWMAXIMIZED, ewNoWait, ErrorCode); // 等待窗口加载(最多等待5秒) ExeHWND := WaitForWindow('ABC窗口标题', 5000); if ExeHWND <> 0 then begin // 将ABC窗口设置为顶层(不改变位置和大小) SetWindowPos(ExeHWND, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE or SWP_NOSIZE); end; end; // 启动网页 ShellExec('', insSiteURLEN, '', '', SW_SHOW, ewNoWait, ErrorCode); end; end;
方案2:保留原Run段,在安装退出前置顶窗口
如果需要保留原Run段配置,可以在安装程序即将退出时,尝试查找ABC.exe的窗口并设置置顶:
修改代码段内容
const insSiteURLEN = 'https://example.com'; // Windows API常量 HWND_TOPMOST = -1; SWP_NOMOVE = $0002; SWP_NOSIZE = $0001; // 引入Windows API函数 procedure SetWindowPos(hWnd: HWND; hWndInsertAfter: HWND; X, Y, cx, cy: Integer; uFlags: UINT); external 'SetWindowPos@user32.dll stdcall'; function FindWindow(lpClassName, lpWindowName: PChar): HWND; external 'FindWindowA@user32.dll stdcall'; // 等待目标窗口出现,超时返回0 function WaitForWindow(const WindowTitle: string; Timeout: Integer): HWND; var StartTime: DWORD; begin Result := 0; StartTime := GetTickCount; while (GetTickCount - StartTime < Timeout) do begin // 替换为ABC.exe实际的窗口标题 Result := FindWindow(nil, PChar('ABC窗口标题')); if Result <> 0 then Break; Sleep(100); end; end; // 原网页启动逻辑不变 procedure CurStepChanged(CurStep: TSetupStep); var ErrorCode: Integer; begin if CurStep=ssDone then begin ShellExec('', insSiteURLEN, '', '', SW_SHOW, ewNoWait, ErrorCode); end; end; // 在安装程序退出前尝试置顶ABC窗口 procedure DeinitializeSetup(); var ExeHWND: HWND; begin ExeHWND := WaitForWindow('ABC窗口标题', 3000); if ExeHWND <> 0 then begin SetWindowPos(ExeHWND, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE or SWP_NOSIZE); end; end;
注意事项
- 请将代码中的
ABC窗口标题替换为ABC.exe实际的窗口标题(可通过窗口探测器工具获取)。 - 如果ABC.exe的窗口标题不固定,可以改用窗口类名查找(将
FindWindow(nil, PChar('标题'))改为FindWindow(PChar('窗口类名'), nil))。
内容的提问来源于stack exchange,提问作者Rohit Arora
相关产品推荐
相关产品推荐

