【发布时间】:2018-05-10 23:35:11
【问题描述】:
我需要一些关于 Inno 设置的帮助。
我的问题是让它放置“文件”并在我希望它们“盲目”的地方执行“操作”。
长话短说,除了一个例外,似乎我想在“System32”文件夹中/在“SysWow64”文件夹中/上做的每一件事。我怎么称呼它似乎并不重要,{sys}, {syswow64}, {sd}\windows\system32, {sd}\windows\syswow64,或者在我的代码部分,%systemdrive%\windows\system32, % systemdrive%\windows\syswow64,或 Expandconstant('{sys}')\filename.exe 等。我什至尝试过硬编码“c:\windows\system32\filename.exe”等等。在除一个之外的所有情况下,它都在 syswow64 文件夹中/中进行。
我知道 system32 和 syswow64 文件夹之间的区别。 (64 位 vs 32 位)我花了一个多星期的时间试图让我的代码把东西放在我告诉它“盲目”的地方。许多论坛上的大量研究,包括这里,似乎都没有提供好的信息和清晰的例子来告诉我如何拥有我需要的控制权。我知道哪个文件是 32 位的,哪个是 64 位的,以及每个文件应该进入哪个文件夹。但是 Inno Setup,错误地认为它知道得更好。
我希望我可以关闭该功能并使其使用我在代码等中编写它们时选择的绝对路径,但我还没有找到一种方法来做到这一点,所以我问如何让 Inno Setup 放置东西我告诉它去哪里,而不是它认为应该去哪里。
无论我如何尝试,我能做的最好的就是让它正确备份我将要覆盖的文件在 system32 和 syswow64 文件夹中。之后,“一切”总是在 syswow64 文件夹上完成,同样,无论我如何编码路径或使用什么标志,例如 64 位等。
我对这个程序的目标有两个,主要是学习如何使用 Inno Setup 来控制文件/文件夹,根据需要更改权限,复制目标文件,然后恢复权限等。我可以用 .bat 文件整天做到这一点。但我想使用 Inno Setup,因为它可以帮助我完成项目的“卸载”部分,这将撤消我想要进行的更改并将文件恢复到其原始配置等。(该项目的这一部分可能需要我的回到这个论坛寻求更多帮助)
这个特定代码要做的是将 Windows 10 计算器替换为我更喜欢的 Windows 7 版本。而且我想使用 Inno Setup,以便我可以让“卸载程序”将其全部放回。我知道其他人已经编写了代码来执行此操作,并且我可以从受信任的来源访问这些程序,我确信这些程序不会冒充“好”的“邪恶”,但在我的企业环境中,我不能冒险和我可以确定这样的代码没有恶意的唯一 100000% 方法是自己编写。另外,正如我所说,它提供了一次学习多种技术的绝佳机会。
正如我所说,我可以,并且已经编写了一个 .bat 文件,它可以备份现有的 calc.exe 文件,在 64 位版本的 Win 10 中存在于 system32 和 syswow64 文件夹中,这就是我需要的原因我的代码对“两个”文件夹执行操作,并将它们替换为相应的 Win 7 版本等等,所以我知道可以这样做。我只需要知道如何在 Inno Setup 中进行操作。我的代码,由于使用路径语法,有几个不同的版本,都能够备份和覆盖 syswow64 中的 calc.exe 文件,但在 64 位 Win 10 操作系统上不能覆盖 system32。
我的代码发布在下面。在其中,您可以看到许多注释行,它们显示了我在需要时尝试放入路径的不同方式。您还将看到,我试图不需要在调用 ICACLS.exe 和 Takeown.exe 时嵌入 .bat 文件以进行权限控制,并且我正在使用(可能是错误的)“Beforinstall”选项来备份权限然后在目标文件上进行更改,以便我可以覆盖它等。我还试图避免在“运行”部分做任何事情,因为在这个项目中不需要这样做。我也有很多消息框要给我反馈,这些反馈将在最终版本中被注释掉,并且“/k”将更改为“/c”,或者,如果我可以让它工作,只需调用直接使用 ICACLS.exe 和 Takeown.exe 程序,而不是先使用“cmd.exe”。我已经完成了这项工作,但切换到带有 /k 的 cmd.exe 方法,以便在此故障排除阶段等获得更好的反馈。此代码预计将在 Win 10 x64 操作系统上运行 99.99%,但必须也能够正确处理在 Win 10 x86 操作系统上运行。 (我为这个项目使用 Win 10 x64 V1709)
; 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;
不知何故,在“文件”部分的前 3 行中,我能够让程序正确创建一个名为“W10CalcBak”的子文件夹,并将正确的“calc.exe”文件复制到 system32和 syswow64 文件夹。但在那之后,一切似乎都只发生在 syswow64 文件夹中。我已经尝试在第一个三个“备份目标”代码行中运行“安装前”部分,现在它在“文件”部分的部分中,我实际上替换了 calc.exe 文件。结果都一样。
当我运行当前编写的代码时,它将使用以下 3 行代码正确执行备份文件部分。
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
在下图中,您可以看到两个备份文件夹等.....Opps 愚蠢的认为不会让我放图片... WAAA,并说它会放一个链接。不是很聪明。我不知道为什么它会认为这会起作用,因为图片位于许多防火墙后面的本地 PC 上的本地高清上,而不是在网页等上,甚至不在具有“IIs”设置或安装等的系统上。 ...
然后它通过以下代码行中的“BeforeInstall:ChangeCalcPerms”选项转到“Proceedure”中名为“ChangeCalcPerms”的第一行。
Source: "C:\InstallScripts\ClasicCalculator\Windows\SysWOW64\*.*"; DestDir: "{syswow64}"; Permissions: authusers-full; Flags: createallsubdirs recursesubdirs overwritereadonly; BeforeInstall: ChangeCalcPerms; Check: IsWindows10 and IsWin64
那时我有许多 msgbox 行来帮助我查看它在做什么等。
当显示第一个消息框时,其中包含“已解决”的路径信息,如下图所示,它设置为正确的 system32 而不是 syswow64 文件夹。单击确定后,将打开一个 DOS 窗口,给出“ICACLS.exe”命令,下一张图片将显示在 DOS 窗口中使用了 system32 的正确路径,然后在我退出该 DOS 窗口后第三张图片结果消息框返回正确的成功代码“0”。但是“calc.perms”不在“system32”文件夹中,即使在我能看到的所有内容中它都显示 system32。它位于“syswow64”文件夹中。这就是我需要停止/控制的。我需要该行来处理 system32 文件夹而不是 syswow64 文件夹。
好的,没有图片,请参阅上面的 cmets。但请相信我,它在所有正确的位置显示“system32”,但它正在“syswow64”中完成所有工作。
我正在编写代码并在其上编译的 Win 7 系统的源文件存储在两个文件夹中,system32 和 syswow64 以及具有正确 calc.exe.mui 语言的 en-US 子文件夹文件等。我知道哪个是 64 位版本,哪个来自 system32 文件夹,哪个是 32 位版本。但最后唯一复制的文件是 syswow64 文件夹中的 32 位版本,没有复制 64 位版本,可能是因为权限不允许,因为由于我的问题,它们没有得到应有的设置让它在我想要的时候使用和操作 system32 文件夹等。
我会展示更多图片来展示它似乎如何正确解析路径,但似乎只在 syswow64 文件夹中执行操作,但我不能,所以我只想问是否有人愿意查看代码,看看他们是否能找到我做错的地方并解释我如何纠正它。
非常感谢所有试图帮助我的人,
拉尔夫
【问题讨论】:
-
请为您的安装程序发布安装日志。对于您的屏幕截图,如果您不能自己托管文件,可以将文件上传到 imgur.com 等图片托管网站。
-
您不能覆盖受保护的系统文件。打开具有管理员权限的 cmd 窗口。您现在位于 system32 文件夹中。输入
ren calc.exe calc.off你会得到一个错误。或move calc.exe C:\calc.exe -
我承认,我没有完整阅读您的问题(这个网站太长了)。但我的印象是您知道如何在常规部分处理 System32/SysWow64 问题,例如
[Files](使用64bit标志)。但是[Code]部分有问题。在那里你需要使用EnableFsRedirection函数:Inno Setup: Checking existence of a file in 32-bit System32 (Sysnative) folder。
标签: inno-setup