This question already has an answer here:
-
A command in a .bat file is unrecognized when the .bat file is called from an Inno Setup but works fine when I run the bat file manually
2 answers
I am trying to refresh the Windows icon cache using the well known and documented method of calling ie4uinit.exe -ClearIconCache
for anything below Window 10 and ie4uinit.exe -Show
on Windows 10 and above:
[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
Both commands work as expected when run in Explorer or at a command prompt. They also work correctly in Inno Setup when running on an x86 system. However, on an x64 system, the following error is produced:
The path to the file, using the {sys}
constant, resolves correctly and the file exists and can be seen both in Explorer and in a directory listing at the command prompt:
The following variation of the above code, running through the command prompt, also fails in much the same way, although it is silent and only indicated by an exit code of 1 in the install log.
[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
I have already read clear icon cache in win 7 programmatically - execute ie4uinit.exe-ClearIconCache using C# or Visual Basic, which also has mention of this being a problem in Inno Setup (towards the bottom) and tried the workaround to copy the file and run it from elsewhere. However, attempting to copy the file to another location, using the FileCopy
function, also failed to find it in C:\Windows\System32
. I also tried running the same command in the [Code]
section using the Exec
function, but this also fails to find it in C:\Windows\System32
.
I considered making a copy of the file and installing it to the temp directory to run it from there, but this file is a different version on each Windows version, so this is not really a viable solution, especially as, being a system file, it may also change in the future.
The accepted answer in the above question seems to be to build the executable for 'Any CPU' rather than 'x86'. However, I am not sure if this can be done in Inno Setup and also if doing so would have any unforeseen side effects on the installers behaviour?
Is there any way to resolve or work around this in Inno Setup?
A far simpler and better solution (thanks for the links Martin) is to have two duplicated [Run]
entries for x64 with Check: IsWin64
and Flags: 64bit
and to add Check: not IsWin64
to the original lines:
[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
I finally figured this out. Inno Setup cannot find the file as, rather confusingly, despite it displaying that it is looking in C:\Windows\System32
, Windows file redirection is actually silently causing it to look in C:\Windows\SysWOW64
, where ie4uinit.exe
does not exist. The solution, therefore, is to temporarily disable file redirection in the [Code]
section, using the [Run]
section BeforeInstall
and AfterInstall
directives, followed by the EnableFsRedirection
function, after which Inno Setup can now see and access the actual C:\Windows\System32
directory, copy the file to the temp directory and run it from there, before restoring file redirection to it's previous state:
[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;