You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现InnoSetup始终静默运行并等待进程完成

实现InnoSetup强制静默并等待进程完成的方案

原方案通过ShellExecute启动静默进程,但无法等待其完成。要实现等待功能,需改用能获取进程句柄的CreateProcess API,配合WaitForSingleObject等待进程结束。以下是修改后的完整代码:

[Setup]
AppName=My Program
AppVersion=1.5
DefaultDirName={pf}\My Program

[Code]
#ifdef UNICODE
  #define AW "W"
#else
  #define AW "A"
#endif

type
  TStartupInfo = record
    cb: DWORD;
    lpReserved: string;
    lpDesktop: string;
    lpTitle: string;
    dwX: DWORD;
    dwY: DWORD;
    dwXSize: DWORD;
    dwYSize: DWORD;
    dwXCountChars: DWORD;
    dwYCountChars: DWORD;
    dwFillAttribute: DWORD;
    dwFlags: DWORD;
    wShowWindow: Word;
    cbReserved2: Word;
    lpReserved2: Byte;
    hStdInput: THandle;
    hStdOutput: THandle;
    hStdError: THandle;
  end;

  TProcessInformation = record
    hProcess: THandle;
    hThread: THandle;
    dwProcessId: DWORD;
    dwThreadId: DWORD;
  end;

function CreateProcess(lpApplicationName: string; lpCommandLine: string;
  lpProcessAttributes: DWORD; lpThreadAttributes: DWORD; bInheritHandles: Boolean;
  dwCreationFlags: DWORD; lpEnvironment: DWORD; lpCurrentDirectory: string;
  var lpStartupInfo: TStartupInfo; var lpProcessInformation: TProcessInformation): Boolean;
  external 'CreateProcess{#AW}@kernel32.dll stdcall';

function WaitForSingleObject(hHandle: THandle; dwMilliseconds: DWORD): DWORD;
  external 'WaitForSingleObject@kernel32.dll stdcall';

function CloseHandle(hObject: THandle): Boolean;
  external 'CloseHandle@kernel32.dll stdcall';

const
  INFINITE = $FFFFFFFF;
  SW_SHOW = 5;
  STARTF_USESHOWWINDOW = $00000001;

function InitializeSetup: Boolean;
var
  StartupInfo: TStartupInfo;
  ProcessInfo: TProcessInformation;
  CmdLine: string;
begin
  Result := WizardSilent;
  if not Result then
  begin
    // 构造带静默参数的启动命令行,路径加引号避免空格问题
    CmdLine := ExpandConstant('"{srcexe}" /SILENT');
    // 初始化启动信息结构
    FillChar(StartupInfo, SizeOf(StartupInfo), 0);
    StartupInfo.cb := SizeOf(StartupInfo);
    StartupInfo.wShowWindow := SW_SHOW;
    StartupInfo.dwFlags := STARTF_USESHOWWINDOW;

    // 启动静默安装进程
    if CreateProcess('', CmdLine, 0, 0, False, 0, 0, '', StartupInfo, ProcessInfo) then
    begin
      // 无限等待进程完成,如需超时可替换为具体毫秒数(如300000=5分钟)
      WaitForSingleObject(ProcessInfo.hProcess, INFINITE);
      // 释放进程和线程句柄,避免资源泄漏
      CloseHandle(ProcessInfo.hThread);
      CloseHandle(ProcessInfo.hProcess);
      // 原进程直接退出,不启动非静默界面
      Result := False;
    end
    else
    begin
      // 启动失败时,允许原非静默安装流程继续
      Result := True;
    end;
  end;
end;

核心要点说明:

  • 改用CreateProcess:相比ShellExecute,它能返回新进程的句柄,这是实现等待功能的基础。
  • 等待进程结束:WaitForSingleObject传入进程句柄和INFINITE参数,会一直阻塞到静默安装进程退出。
  • 资源清理:进程结束后必须调用CloseHandle释放句柄,防止系统资源泄漏。
  • 命令行容错:给程序路径添加引号,避免路径含空格时启动失败。

特殊场景处理:

如果静默安装会触发系统重启,WaitForSingleObject会在安装程序准备重启时提前返回(进程未完全完成)。这种情况可以通过获取进程退出码,判断是否需要重启,再补充对应的逻辑(比如提示用户重启或等待系统重启完成)。

内容的提问来源于stack exchange,提问作者audev

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 10:32:46