I need some help with Inno Setup please.
My problem is getting it to place "files" and perform "actions" where I want them "BLINDLY".
To make a long story short, with but one exception, it seems that every thing I want done to/in the "System32" folder is ending up in/on the "SysWow64" folder. It does not seem to matter how I call it, {sys}, {syswow64}, {sd}\windows\system32, {sd}\windows\syswow64, or in my code section, %systemdrive%\windows\system32, %systemdrive%\windows\syswow64, or Expandconstant('{sys}')\filename.exe, and so on. I even tried hard coding "c:\windows\system32\filename.exe" and so on. In every case except one, it did it on/in the syswow64 folder.
I know the difference between the system32 and the syswow64 folder. (64bit vs 32bit) I have spent over a week trying to get my code to put things where I tell it to "blindly". Lots of research in the many forums, including here, none seem to give good information and clear examples that show me how to have the control I need. I know which file is 32 bit, which is 64 bit and which folder each should go in to. But Inno Setup, incorrectly thinks it knows better.
I wish I could turn off that feature and make it use the absolute paths I choose as I write them in code etc., but I have not found a way to do that so I am asking how to make Inno Setup put things where I tell it to go, not where it thinks it should go.
No matter how I have tried, the best I can do is get it to back up the files I am going to overwrite in the system32 and in the syswow64 folder correctly. After that "everything" is always done on the syswow64 folder, again, no matter how I code the path or what flags I use such as 64bit, etc.
My goal with this program is two fold, the main one is to learn how to use Inno Setup to take control of a file/folder, changing permissions as needed, copying over the target file, then restoring the perms etc. I can do this all day long with .bat files. But I want to use Inno Setup because it can help me do the Uninstall" part of my project which will undo the changes I want to make and restore the files back to their original configuration etc. (That part of this project will probably require my coming back to this forum for additional help)
What this specific code is going to do is replace the Windows 10 calculator with the Windows 7 version, which I prefer. And I want to use Inno Setup so that I can have an "Uninstaller" put it all back. I know others have already written code to do this, and I have access to those programs from trusted sources that I am sure are not putting out "Evil" posing as "Good", but in my enterprise environment, I cannot take a chance and the only 100000% way I can be sure such code is evil free is to write it myself. Plus, as I said, it provides an excellent opportunity to learn several techniques at once.
As I said I can, and have written a .bat file which can back up the existing calc.exe files, which in the 64 bit version of Win 10 exist in both the system32 and syswow64 folders, which is why I need my code to do things to "both" folders, and replace them with the corresponding Win 7 versions and so on so I know it is possible to do this. I just need to know how to do it in Inno Setup. My code, several different versions due to playing with paths syntax, have all been able to backup and overwrite the calc.exe file in syswow64, but not system32 on a 64bit Win 10 OS.
My code is posted below. In it you can see many commented lines which show the different ways I have tried to put in the paths as I need them. You will also see that I am trying not to need to embed a .bat file with my calls to ICACLS.exe and Takeown.exe for permissions control and I am using, maybe incorrectly, the "Beforinstall" option to have the permissions backed up and then changed on the target file so that I can overwrite it etc. I am also trying to avoid doing anything in the "run" section as that should not be needed in this project. I also have a lot of message boxes to give me feed back which will be commented out on the final version as well as the "/k" will be changed to "/c" or, if I can get it to work, just call the ICACLS.exe and Takeown.exe programs directly instead of shelling out to "cmd.exe" first. I have had that work, but switched to the cmd.exe method with the /k for better feed back during this trouble shooting phase etc. This code is expected to be run 99.99% of the time on a Win 10 x64 OS, but must be able to handle correctly being run on a Win 10 x86 OS as well. (I am on Win 10 x64 V1709 for this project)
; Script generated by the Inno Setup Script Wizard.
; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES!
[Setup]
; NOTE: The value of AppId uniquely identifies this application.
; Do not use the same AppId value in installers for other applications.
; (To generate a new GUID, click Tools | Generate GUID inside the IDE.)
AppId={{C771AFC7-CC36-4749-962D-119AD2671213}
AppName=Clasic Calculator
AppVerName=Classic Calculator Win 7 Style
AppPublisher=ACollege
AppPublisherURL=www.Acollege.edu
AppSupportURL=www.Acollege.edu
AppUpdatesURL=www.Acollege.edu
CreateAppDir=no
OutputDir=C:\InstallScripts\ClasicCalculator\Setup
OutputBaseFilename=SetupClasicCalc
ArchitecturesAllowed= x86 x64
;ArchitecturesInstallIn64BitMode=
PrivilegesRequired=admin
MinVersion = 0,5.0
Compression=lzma
SolidCompression=yes
CreateUninstallRegKey=yes
UpdateUninstallLogAppName=yes
uninstallable=yes
SetupIconFile="C:\InstallScripts\ClasicCalculator\calc-1.ico"
[Languages]
;Name: "english"; MessagesFile: "compiler:ASpyFolder.isl"
[Dirs]
;Win 10 Section
[Files]
;Windows 10 Section
;Testline for how is it running
;Source: "C:\InstallScripts\ClasicCalculator\Windows\SysWOW64\*.*"; DestDir: "c:\TempTest"; Permissions: authusers-full; Flags: createallsubdirs recursesubdirs overwritereadonly; Check: WhatIsIt
Source: "{syswow64}\calc.exe"; DestDir: "{syswow64}\W10CalcBak"; DestName: "Calc.exe"; Permissions: authusers-full; Flags: external; Check: IsWindows10 and not IsWin64
Source: "{sys}\calc.exe"; DestDir: "{sys}\W10CalcBak"; DestName: "Calc.exe"; Permissions: authusers-full; Flags: 64bit external; Check: IsWindows10 and IsWin64
;Source: "{sd}\windows\system32\calc.exe"; DestDir: "{sd}\windows\system32\W10CalcBak"; DestName: "Calc.exe"; Permissions: authusers-full; Flags: external; BeforeInstall: ChangeCalcPerms; Check: IsWindows10 and not IsWin64
;Source: "{sd}\windows\system32\calc.exe"; DestDir: "{sd}\windows\system32\W10CalcBak"; DestName: "Calc.exe"; Permissions: authusers-full; Flags: 64bit external; BeforeInstall: ChangeCalcPerms; Check: IsWindows10 and IsWin64
Source: "{syswow64}\calc.exe"; DestDir: "{syswow64}\W10CalcBak"; DestName: "Calc.exe"; Permissions: authusers-full; Flags: external; Check: IsWindows10 and IsWin64
Source: "C:\InstallScripts\ClasicCalculator\Windows\SysWOW64\*.*"; DestDir: "{syswow64}"; Permissions: authusers-full; Flags: createallsubdirs recursesubdirs overwritereadonly; BeforeInstall: ChangeCalcPerms; Check: IsWindows10 and IsWin64
Source: "C:\InstallScripts\ClasicCalculator\Windows\System32\*.*"; DestDir: "{sys}"; Permissions: authusers-full; Flags: createallsubdirs recursesubdirs overwritereadonly; Check: IsWindows10 and IsWin64
Source: "C:\InstallScripts\ClasicCalculator\Windows\SysWOW64\*.*"; DestDir: "{syswow64}"; Permissions: authusers-full; Flags: createallsubdirs recursesubdirs overwritereadonly; BeforeInstall: ChangeCalcPerms; Check: IsWindows10 and not IsWin64
;Source: "{win}\system32\en-US\calc.exe.mui"; DestDir: "{win}\system32\W10CalcBak"; DestName: "calc.exe.mui"; Permissions: authusers-full; Flags: external; Check: IsWindows10
[Registry]
[INI]
[Run]
[Code]
Function WhatIsIt(): Boolean;
begin
if Is64BitInstallMode then
begin
MsgBox('Installing in 64-bit mode', mbInformation, MB_OK)
end
else
begin
MsgBox('Installing in 32-bit mode', mbInformation, MB_OK);
end;
if IsWin64 then
begin
MsgBox('This is 64bit system', mbInformation, MB_OK)
MsgBox('(PF64)-bit program files reside in: ' + ExpandConstant('{pf64}'), mbInformation, MB_OK);
MsgBox('(PF32)-bit program files reside in: ' + ExpandConstant('{pf32}'), mbInformation, MB_OK);
MsgBox('(PF) program files reside in: ' + ExpandConstant('{pf}'), mbInformation, MB_OK);
MsgBox('(SYS) program files reside in: ' + ExpandConstant('{sys}'), mbInformation, MB_OK);
MsgBox('(SYS64) program files reside in: ' + ExpandConstant('{syswow64}'), mbInformation, MB_OK);
MsgBox('(SYS32) program files reside in: ' + ExpandConstant('{syswow64}'), mbInformation, MB_OK);
end
else
begin
MsgBox('This is NOT 64bit system', mbInformation, MB_OK)
MsgBox('32-bit program files reside in: ' + ExpandConstant('{pf32}'), mbInformation, MB_OK);
end;
Exit
end;
Procedure ChangeCalcPerms();
var
CommandLine: String;
ResultCode: Integer;
begin
CommandLine := '"' + ExpandConstant('{sys}') + '\calc.exe"' + ' /save ' + '"' + ExpandConstant('{sys}') + '\calc.perms"'
(*CommandLine := '"' + '%systemdrive%\windows\system32\calc.exe"' + ' /save ' + '"' + '%systemdrive%\windows\system32\calc.perms"'*)
MsgBox('System 32 Backup Comandline is: ' + CommandLine, mbInformation, MB_OK);
shellExec('','CMD.exe', '/k ' + 'ICACLS.exe ' + commandline, '', SW_SHOW, ewWaitUntilTerminated, ResultCode)
(*Exec('CMD.exe', '/k ' + 'ICACLS.exe ' + commandline, '', SW_SHOW, ewWaitUntilTerminated, ResultCode)*)
(*Exec('ICACLS.exe', CommandLine, '', SW_SHOW, ewWaitUntilTerminated, ResultCode)*)
MsgBox('System 32 Backup Result is: ' + IntToStr(ResultCode), mbInformation, MB_OK);
CommandLine := '/F "' + ExpandConstant('{sys}') + '\calc.exe"' + ' /A'
(*CommandLine := '/F "' + '%systemdrive%\windows\system32\calc.exe"' + ' /A'*)
MsgBox('System 32 Make Owner Admin Comandline is: ' + CommandLine, mbInformation, MB_OK);
ShellExec('','CMD.exe', '/k ' + 'Takeown.exe ' + commandline, '', SW_SHOW, ewWaitUntilTerminated, ResultCode)
(*Exec('CMD.exe', '/k ' + 'Takeown.exe ' + commandline, '', SW_SHOW, ewWaitUntilTerminated, ResultCode)*)
(*Exec('Takeown.exe', CommandLine, '', SW_SHOW, ewWaitUntilTerminated, ResultCode)*)
MsgBox('System 32 Make Owner Admin Result is: ' + IntToStr(ResultCode), mbInformation, MB_OK);
CommandLine := '"' + ExpandConstant('{sys}') + '\calc.exe"' + ' /grant Administrators:f'
(*CommandLine := '"' + '%systemdrive%\windows\system32\calc.exe"' + ' /grant Administrators:f'*)
MsgBox('System 32 Give Admin Full Perms Comandline is: ' + CommandLine, mbInformation, MB_OK);
ShellExec('','CMD.exe', '/k ' + 'ICACLS.exe ' + commandline, '', SW_SHOW, ewWaitUntilTerminated, ResultCode)
(*Exec('CMD.exe', '/k ' + 'ICACLS.exe ' + commandline, '', SW_SHOW, ewWaitUntilTerminated, ResultCode)*)
(*Exec('ICACLS.exe', CommandLine, '', SW_SHOW, ewWaitUntilTerminated, ResultCode)*)
MsgBox('System 32 Give Admin Full Perms Result is: ' + IntToStr(ResultCode), mbInformation, MB_OK);
CommandLine := '"' + '%systemdrive%\windows\sysWOW64\calc.exe"' + ' /save ' + '"' + '%systemdrive%\windows\sysWOW64\calc.perms"'
MsgBox('Syswow 64 Backup Comandline is: ' + CommandLine, mbInformation, MB_OK);
ShellExec('','CMD.exe', '/k ' + 'ICACLS.exe ' + commandline, '', SW_SHOW, ewWaitUntilTerminated, ResultCode)
(*Exec('CMD.exe', '/k ' + 'ICACLS.exe ' + commandline, '', SW_SHOW, ewWaitUntilTerminated, ResultCode)*)
(*Exec('ICACLS.exe', CommandLine, '', SW_SHOW, ewWaitUntilTerminated, ResultCode)*)
MsgBox('Syswow 64 Backup Result is: ' + IntToStr(ResultCode), mbInformation, MB_OK);
CommandLine := '/F "' + '%systemdrive%\windows\sysWOW64\calc.exe"' + ' /A'
MsgBox('Syswow 64 Make Owner Admin Comandline is: ' + CommandLine, mbInformation, MB_OK);
ShellExec('','CMD.exe', '/k ' + 'Takeown.exe ' + commandline, '', SW_SHOW, ewWaitUntilTerminated, ResultCode)
(*Exec('CMD.exe', '/k ' + 'Takeown.exe ' + commandline, '', SW_SHOW, ewWaitUntilTerminated, ResultCode)*)
(*Exec('Takeown.exe', CommandLine, '', SW_SHOW, ewWaitUntilTerminated, ResultCode)*)
MsgBox('Syswow 64 Make Owner Admin Result is: ' + IntToStr(ResultCode), mbInformation, MB_OK);
CommandLine := '"' + '%systemdrive%\windows\sysWOW64\calc.exe"' + ' /grant Administrators:f'
MsgBox('Syswow 64 Give Admin Full Perms Comandline is: ' + CommandLine, mbInformation, MB_OK);
ShellExec('','CMD.exe', '/k ' + 'ICACLS.exe ' + commandline, '', SW_SHOW, ewWaitUntilTerminated, ResultCode)
(*Exec('CMD.exe', '/k ' + 'ICACLS.exe ' + commandline, '', SW_SHOW, ewWaitUntilTerminated, ResultCode)*)
(*Exec('ICACLS.exe', CommandLine, '', SW_SHOW, ewWaitUntilTerminated, ResultCode)*)
MsgBox('Syswow 64 Give Admin Full Perms Result is: ' + IntToStr(ResultCode), mbInformation, MB_OK);
CommandLine := '"' + '%systemdrive%\windows\sysWOW64\calc.exe"' + ' /grant System:f'
MsgBox('Syswow 64 Give System Full Perms Comandline is: ' + CommandLine, mbInformation, MB_OK);
ShellExec('','CMD.exe', '/k ' + 'ICACLS.exe ' + commandline, '', SW_SHOW, ewWaitUntilTerminated, ResultCode)
(*Exec('CMD.exe', '/k ' + 'ICACLS.exe ' + commandline, '', SW_SHOW, ewWaitUntilTerminated, ResultCode)*)
(*Exec('ICACLS.exe', CommandLine, '', SW_SHOW, ewWaitUntilTerminated, ResultCode)*)
MsgBox('Syswow 64 Give System Full Perms Result is: ' + IntToStr(ResultCode), mbInformation, MB_OK);
(*SECDeleteSYSWOW*)
CommandLine := 'Del "' + '%systemdrive%\windows\sysWOW64\calc.exe"'
MsgBox('Syswow 64 Del Calc.exe Comandline is: ' + CommandLine, mbInformation, MB_OK);
ShellExec('','CMD.exe', '/k ' + commandline, '', SW_SHOW, ewWaitUntilTerminated, ResultCode)
(*Exec('CMD.exe', '/k ' + commandline, '', SW_SHOW, ewWaitUntilTerminated, ResultCode)*)
(*Exec('ICACLS.exe', CommandLine, '', SW_SHOW, ewWaitUntilTerminated, ResultCode)*)
MsgBox('Syswow 64 Del Calc.exe Result is: ' + IntToStr(ResultCode), mbInformation, MB_OK);
end;
function IsX64: Boolean;
begin
Result := Is64BitInstallMode and (ProcessorArchitecture = paX64);
(*MsgBox('IsWindows64 Result is: ' + inttostr(Integer(Result)), mbInformation, MB_OK)*)
end;
function IsIA64: Boolean;
begin
Result := Is64BitInstallMode and (ProcessorArchitecture = paIA64);
end;
function IsOtherArch: Boolean;
begin
Result := not IsX64 and not IsIA64;
end;
function IsWindowsXP: Boolean;
var
Version: TWindowsVersion;
S: String;
begin
GetWindowsVersionEx(Version);
Result := Version.NTPlatform and (Version.Major = 5) and (Version.Minor = 1);
end;
function IsWindowsVista: Boolean;
var
Version: TWindowsVersion;
S: String;
begin
GetWindowsVersionEx(Version);
Result := Version.NTPlatform and (Version.Major= 6) and (Version.Minor = 0);
end;
function IsWindows7: Boolean;
var
Version: TWindowsVersion;
S: String;
begin
GetWindowsVersionEx(Version);
Result := Version.NTPlatform and (Version.Major = 6) and (Version.Minor = 1);
end;
function IsWindows10: Boolean;
var
Version: TWindowsVersion;
S: String;
begin
GetWindowsVersionEx(Version);
Result := Version.NTPlatform and (Version.Major= 10) and (Version.Minor = 0);
(*MsgBox('IsWindows10 Result is: ' + inttostr(Integer(Result)), mbInformation, MB_OK)*)
end;
function IsWindowsVista_or_7: Boolean;
var
Version: TWindowsVersion;
S: String;
begin
GetWindowsVersionEx(Version);
Result := Version.NTPlatform and (Version.Major = 6) and ((Version.Minor = 1) or (Version.Minor = 0));
end;
function IsWindowsVista_or_7_or_8: Boolean;
var
Version: TWindowsVersion;
S: String;
begin
GetWindowsVersionEx(Version);
Result := Version.NTPlatform and (Version.Major = 6) and ((Version.Minor = 2) or (Version.Minor = 1) or (Version.Minor = 0));
end;
function IsWindows8: Boolean;
var
Version: TWindowsVersion;
S: String;
begin
GetWindowsVersionEx(Version);
Result := Version.NTPlatform and (Version.Major = 6) and (Version.Minor = 2);
end;
Somehow, within the first 3 lines of the "Files" section I am able to get the program to correctly create a sub folder called "W10CalcBak" and copy the correct "calc.exe" file in to it in both the system32 and the syswow64 folders. But after that, everything seems to happen to the syswow64 folder only. I have tried running the "Beforeinstall" part in the 1st three "backup the targets" lines of code, and where it is now in the part of the "Files" section where I actually replace the calc.exe files. All with the same result.
When I run the code as currently written it will execute the backup the files part correctly using the following 3 lines of code.
Source: "{syswow64}\calc.exe"; DestDir: "{syswow64}\W10CalcBak"; DestName: "Calc.exe"; Permissions: authusers-full; Flags: external; Check: IsWindows10 and not IsWin64
Source: "{sys}\calc.exe"; DestDir: "{sys}\W10CalcBak"; DestName: "Calc.exe"; Permissions: authusers-full; Flags: 64bit external; Check: IsWindows10 and IsWin64
Source: "{syswow64}\calc.exe"; DestDir: "{syswow64}\W10CalcBak"; DestName: "Calc.exe"; Permissions: authusers-full; Flags: external; Check: IsWindows10 and IsWin64
In the below picture you can see the two backup folders etc..... Opps Stupid think wont let me put up pictures... WAAA, and says it will put in a link instead. Not very smart of it. I don't know why it would think that is going to work as the picture is on a local HD on a local PC behind many firewalls and is not on a webpage etc or even a system with "IIs" setup or installed etc.....
Then it goes to the first line in the "Proceedure" called "ChangeCalcPerms" via the "BeforeInstall: ChangeCalcPerms" option in the following code line.
Source: "C:\InstallScripts\ClasicCalculator\Windows\SysWOW64\*.*"; DestDir: "{syswow64}"; Permissions: authusers-full; Flags: createallsubdirs recursesubdirs overwritereadonly; BeforeInstall: ChangeCalcPerms; Check: IsWindows10 and IsWin64
At that point I have many msgbox lines to help me see what it is doing etc.
When the first message box is shown it has the "resolved" path info in it which as you can see in the picture below is set to the correct system32 not syswow64 folder. After I click OK, a DOS window opens, the "ICACLS.exe" command is given, the next picture will show that it seems the correct path to system32 was used in the DOS window and then after I exit that DOS window the third picture of the results message box returns the correct success code of "0". But the "calc.perms" is not in the "system32" folder even though in everything I can see it shows system32. It is instead in the "syswow64" folder. That is what I need to stop/control. I need that line to do its work on the system32 folder not the syswow64 one.
OK no pictures, see comments above. But believe me it is showing "system32" in all the right places, but it is doing all the work in "syswow64".
The source files from the Win 7 system that I am writing the code on and compiling it on are stashed in two folders, the system32 and the syswow64 along with the en-US sub folder with the proper calc.exe.mui language file etc. I know which one is the 64bit version, the one from the system32 folder, and which one is the 32 bit version. But in the end the only file copied is the 32 bit version in to the syswow64 folder, the 64 bit version is not copied, probably because the permissions do not allow it as they are not getting set as they should due to the problem I am having getting it to use and act on the system32 folder when I want it to etc.
I would show more pictures that would show how it seems to resolve the paths correctly but yet seems to only do things in the syswow64 folder but I can't so I am just going to ask if anyone out there would please take a look at the code and see if they can find what I am doing wrong and explain how I can correct it.
Thank you VERY VERY much in advance to all who try to help me,
Ralph