Inno Setup - 如何安装 Windows 更新离线安装程序

Inno Setup - How to Install Windows Update Offline Installer

我正在编写一个函数来为我的设备安装一个必需的组件,该组件是基于 PowerShell 构建的。如果找不到特定版本的 PowerShell,我希望安装程序帮助用户安装它。我 运行 遇到的问题是如何适当地调用离线安装程序进行安装。这是我的代码,它是一个通用函数(我正在使用 InnoSetup Dependency Installer):

function SmartExec(product : TProduct; var resultcode : Integer): boolean;
begin
    if (LowerCase(Copy(product.File, Length(product.File) - 2, 3)) = 'exe') then begin
        Result := Exec(product.File, product.Parameters, '', SW_SHOWNORMAL, ewWaitUntilTerminated, resultcode);
    end else begin
        Result := ShellExec('', product.File, product.Parameters, '', SW_SHOWNORMAL, ewWaitUntilTerminated, resultcode);
    end;
end;

我试过使用以下方法:

function SmartExec(product : TProduct; var resultcode : Integer): boolean;
begin
    if (LowerCase(Copy(product.File, Length(product.File) - 2, 3)) = 'exe') then begin
        Result := Exec(product.File, product.Parameters, '', SW_SHOWNORMAL, ewWaitUntilTerminated, resultcode);
  end else if (LowerCase(Copy(product.File, Length(product.File) - 2, 3)) = 'msu') then begin
        Result := ShellExec('', 'wusa.exe ' + product.File, product.Parameters, '', SW_SHOWNORMAL, ewWaitUntilTerminated, resultcode);
    end else begin
        Result := ShellExec('', product.File, product.Parameters, '', SW_SHOWNORMAL, ewWaitUntilTerminated, resultcode);
    end;
end;

当我编译和测试安装程序时,迎接我的是:

我正在将 /quiet /norestart 作为参数传递给 MSU 文件,该文件可在命令提示符下完美执行。

安装文件下载到当前用户%tmp%,我看到了文件。

有任何帮助或意见吗?

.msu 扩展与 wusa.exe 关联,因此现有分支 ShellExec('', product.File, ...) 应该完成这项工作。您不需要添加特定的 msu 分支。


总之,具体分支可以帮助调试,值得一试。

ShellExec function的第二个参数是一个FileName,而你传入wusa.exe xxx.msu,什么是无效的文件名。

这应该有效:

Result := ShellExec('', 'wusa.exe', product.File + ' ' + product.Parameters, ...);

虽然使用 ShellExec 到 运行 可执行文件有点矫枉过正,但请改用普通的 Exec function

Result := Exec('wusa.exe', product.File + ' ' + product.Parameters, ...);

ExecreturnsFalse时,ResultCode是一个Windows错误码,说明执行失败的原因。您得到代码 3,什么是 ERROR_PATH_NOT_FOUND系统找不到指定的路径。)。

看来您使用的路径 (product.File) 无效。

确保您传递 .msu 的完整路径,而不仅仅是文件名。

尝试在调用 Exec 之前记录路径并检查文件是否存在。您可以使用:

Log(Format('Path is [%s], Exists = %d', [product.File, Integer(FileExists(product.File))]));