Inno Setup 无法在 x64 上找到并执行 ie4uinit.exe

Inno Setup unable to find and execute ie4uinit.exe on x64

我正在尝试使用众所周知的记录方法刷新 Windows 图标缓存,该方法调用 ie4uinit.exe -ClearIconCache 低于 Window 10 和 ie4uinit.exe -Show 在 Windows10岁及以上:

[Run]
Filename: "{sys}\ie4uinit.exe"; Parameters: "-ClearIconCache"; StatusMsg: "Rebuilding Windows icon cache..."; Flags: runhidden; Check: not IsWindows10AndAbove
Filename: "{sys}\ie4uinit.exe"; Parameters: "-Show"; StatusMsg: "Rebuilding Windows icon cache..."; Flags: runhidden; Check: IsWindows10AndAbove

当 运行 在资源管理器或命令提示符下时,这两个命令都按预期工作。在 x86 系统上 运行ning 时,它们在 Inno Setup 中也能正常工作。但是,在 x64 系统上,会产生以下错误:

使用 {sys} 常量的文件路径正确解析并且文件存在并且可以在资源管理器和命令提示符下的目录列表中看到:

上述代码的以下变体,运行通过命令提示符,也以大致相同的方式失败,尽管它是无声的并且仅由安装日志中的退出代码 1 指示。

[Run]
Filename: "{cmd}"; Parameters: "/c {sys}\ie4uinit.exe -ClearIconCache"; StatusMsg: "Rebuilding Windows icon cache..."; Flags: runhidden; Check: not IsWindows10AndAbove
Filename: "{cmd}"; Parameters: "/c {sys}\ie4uinit.exe -Show"; StatusMsg: "Rebuilding Windows icon cache..."; Flags: runhidden; Check: IsWindows10AndAbove

我已经阅读了 clear icon cache in win 7 programmatically - execute ie4uinit.exe-ClearIconCache using C# or Visual Basic,其中还提到这是 Inno Setup 中的一个问题(接近底部),并尝试了从其他地方复制文件和 运行 的解决方法。但是,尝试使用 FileCopy 函数将文件复制到另一个位置时,也未能在 C:\Windows\System32 中找到它。我也尝试 运行 使用 Exec 函数在 [Code] 部分中使用相同的命令,但这也无法在 C:\Windows\System32.

中找到它

我考虑制作一个文件的副本并将其安装到临时目录以从那里 运行 它,但是这个文件在每个 Windows 版本上都是不同的版本,所以这不是确实是一个可行的解决方案,特别是作为一个系统文件,它在未来也可能会发生变化。

上述问题中公认的答案似乎是为 'Any CPU' 而不是 'x86' 构建可执行文件。但是,我不确定这是否可以在 Inno Setup 中完成,以及这样做是否会对安装程序行为产生任何不可预见的副作用?

在 Inno Setup 中有什么方法可以解决或解决这个问题吗?

我终于明白了。 Inno Setup 无法找到该文件,尽管它显示它正在查找 C:\Windows\System32,Windows 文件重定向实际上静默地导致它查找 C:\Windows\SysWOW64,其中 [=13] =] 不存在。因此,解决方案是暂时禁用 [Code] 部分中的文件重定向,使用 [Run] 部分 BeforeInstallAfterInstall 指令,然后是 EnableFsRedirection 函数, 之后 Inno Setup 现在可以看到并访问实际的 C:\Windows\System32 目录,将文件复制到临时目录并从那里 运行 它,然后将文件重定向恢复到它以前的状态:

[Run]
Filename: "{tmp}\Config Tools\ie4uinit.exe"; Parameters: "-ClearIconCache"; StatusMsg: "Refreshing Windows icon cache..."; Flags: runhidden; Check: not IsWindows10AndAbove; BeforeInstall: StartRefreshIconCache; AfterInstall: FinishRefreshIconCache
Filename: "{tmp}\Config Tools\ie4uinit.exe"; Parameters: "-Show"; StatusMsg: "Refreshing Windows icon cache..."; Flags: runhidden; Check: IsWindows10AndAbove; BeforeInstall: StartRefreshIconCache; AfterInstall: FinishRefreshIconCache

[Code]
//Start refresh or rebuild of the Windows icon cache
procedure StartRefreshIconCache();
var
  OriginalFileRedirectionState: Boolean;
begin
  if not IsWin64 then
    begin
      if FileCopy(ExpandConstant('{sys}\ie4uinit.exe'), ExpandConstant('{tmp}\Config Tools\ie4uinit.exe'), False) then
        begin
          Log(ExpandConstant('Copied {sys}\ie4uinit.exe to {tmp}\Config Tools\ie4uinit.exe'));
        end;
    end
  else if IsWin64 then
    begin
      //Store Windows file redirection's original state and temporarily disable to allow access to the System32 directory on x64 to allow copy of ie4uinit.exe
      OriginalFileRedirectionState := EnableFsRedirection(False); 
      Log('File redirection temporarily disabled for x64 compatibility.');
      try
        if FileCopy(ExpandConstant('{sys}\ie4uinit.exe'), ExpandConstant('{tmp}\Config Tools\ie4uinit.exe'), False) then
          begin
            Log(ExpandConstant('Copied {sys}\ie4uinit.exe to {tmp}\Config Tools\ie4uinit.exe'));
          end;
      finally
        //Restore file redirection's original state
        EnableFsRedirection(OriginalFileRedirectionState);
        Log('File redirection restored to it''s original state.');
      end;
    end;
end;

//Finish refresh or rebuild of the Windows icon cache
procedure FinishRefreshIconCache();
begin
  if DeleteFile(ExpandConstant('{tmp}\Config Tools\ie4uinit.exe')) then
    begin
      Log(ExpandConstant('Deleted {tmp}\Config Tools\ie4uinit.exe'));    
    end;
end;

一个更简单更好的解决方案(感谢 Martin 提供的链接)是为 x64 设置两个重复的 [Run] 条目 Check: IsWin64Flags: 64bit 并添加 Check: not IsWin64 到原来的行:

[Run]
Filename: "{sys}\ie4uinit.exe"; Parameters: "-ClearIconCache"; StatusMsg: "Refreshing Windows icon cache..."; Flags: runhidden; Check: not IsWindows10AndAbove and not IsWin64
Filename: "{sys}\ie4uinit.exe"; Parameters: "-Show"; StatusMsg: "Refreshing Windows icon cache..."; Flags: runhidden; Check: IsWindows10AndAbove and not IsWin64
Filename: "{sys}\ie4uinit.exe"; Parameters: "-ClearIconCache"; StatusMsg: "Refreshing Windows icon cache..."; Flags: runhidden 64bit; Check: not IsWindows10AndAbove and IsWin64
Filename: "{sys}\ie4uinit.exe"; Parameters: "-Show"; StatusMsg: "Refreshing Windows icon cache..."; Flags: runhidden 64bit; Check: IsWindows10AndAbove and IsWin64