我已经编写了一个通过WIX生成的MSI分发的COM组件。
COM组件具有相当复杂且非静态的注册逻辑,这意味着将注册信息直接嵌入Windows Installer WXS文件中不是可行的选择-必须使用regsvr32
完成注册-这是一个32位COM组件,因此它必须使用32位版本的regsvr32.exe
-在64位Windows上为%SystemRoot%\SysWow64\regsvr32.exe
或在x86 Windows上为%SystemRoot%\System32\regsvr32.exe
。
我注意到使用此WXS XML的WIX存在两个问题:
<InstallExecuteSequence>
<Custom Action="COMRegister" After="InstallFinalize">NOT Installed</Custom>
<Custom Action="COMUnregister" After="InstallInitialize">Installed</Custom>
</InstallExecuteSequence>
<CustomAction Id="COMRegister" Directory="APPLICATIONROOTDIRECTORY" ExeCommand='regsvr32.exe /s "[APPLICATIONROOTDIRECTORY]Component.dll"' />
<CustomAction Id="COMUnregister" Directory="APPLICATIONROOTDIRECTORY" ExeCommand='regsvr32.exe /s /u "[APPLICATIONROOTDIRECTORY]Component.dll"' />
regsvr32.exe
被调用。我注意到resgvr32.exe
的x64版本是在64位系统而不是32位版本上运行的。regsvr32.exe
在没有提升的权限的情况下运行,因此COM注册失败,并显示E_ACCESSDENIED
。对于1.,如果我使用[WindowsFolder]\SysWOW64\regsvr32.exe
硬编码了regsvr32.exe可执行文件的路径,它将起作用,但这在不存在SysWow64
的真实32位计算机上将无法使用。
对于2.我在线阅读了将After="InstallFinalize" to
After =“ RemoveExistingProducts”would cause it to run with elevated permissions, however instead this just gives me errors about
RemoveExistingProducts`更改为未解决的符号名称。
我该如何解决这两个问题?
((在过去两个小时内努力解决此问题后,我相信WIX的作者与H.P. Lovecraft的亲密关系)
我通过编写属于32位可执行文件的自己的中间步骤程序来解决第一个问题,因此该程序始终在WOW上下文中运行,因此它将可靠地调用32位regsvr32.exe
程序。
我发现第二个问题是这些问题:要使CustomAction以提升的权限运行(好吧,在与主安装程序作业相同的安全性上下文中,这些条件必须为真:
<Custom/>" must have
Before =“ InstallFinalize”, and **not**
After =“”any other values for
Before =“”`将无法可靠运行,因为WIX或Windows Installer可能会重新排列操作(错误)。<CustomAction />
具有以下属性明确设置:Execute="deferred"
Impersonate="off"
即使如此,我也不必使用我的帮助程序来正确解析32位regsvr32.exe
。有哪些选项?
我完全不建议使用自我注册,如果您确实必须将File / @ SelfRegCost设置为1,那么使用Windows Installer并不是真正正确的方法。
一种更好的方法是提取注册表值并用WiX写入它们-您也可以利用热量来生成值。
这听起来可能会在以后引起很多问题。尽管听起来您确定要使用此自我注册,但请阅读全文