避免让 MSI 进入兼容模式 "Previous version of Windows"
Avoid to bring MSI in compatibility mode "Previous version of Windows"
我有一个 32 位应用程序的安装程序包(使用 MakeMsi 构建,最初是为 Windows XP 构建的,从那时起就简单地维护了),但无法在现代(64 位)上注册 COM 服务器Windows 系统(7、8、10)。这是我在尝试正常安装 MSI 时看到的:
Application Error
Exception EOleSysError in module xyz at 000F0B01. Error accessing the OLE registry.
如果我将 MSI 置于 兼容模式 Windows 的先前版本,COM 服务器注册成功。由于 “它正在工作” 不知何故,到目前为止我没有投入太多时间来探索原因。但最后,我厌倦了一次又一次地记住我们的客户(有时也是我)这个先决条件,所以我想解决这个问题。
注册(和注销)是通过 CustomActions 完成的,正如我使用 Orca 所见:
"[INSTALLDIR.MYAPP]\placeholder.exe" -regserver
"[INSTALLDIR.MYAPP]\placeholder.exe" -unregserver
对于这些条目中的每一个,Type
是 1122
并且 Source
是 INSTALLDIR.MYAPP
。
我可以想象在安装过程中 COM 服务器是在权限不足的情况下启动的,但是安装程序 运行 不是自动具有管理员权限吗?我的意思是,当我(作为标准用户)通过双击启动安装程序时,它会在实际安装发生之前 显示 UAC 提示符。为什么 COM 服务器没有 运行 注册和注销的提升权限?令人困惑...
我应该如何更改我的 MSI 以使 Windows 安装程序成功处理它?
我假设您知道问题出在您作为自定义操作 运行ning 的可执行文件中,而不是 Windows 安装程序中的任何内容。这意味着问题将出在可执行文件中的代码,它可能是旧的并且与后来的 OS 版本不兼容。您需要查看代码以了解不受支持的功能。
许多安装不需要自行注册。该数据是所有静态数据,可以提取一次并包含在注册表项和其他 COM class 表中的 MSI 文件中。这意味着在安装过程中根本不需要 运行 代码。
在学习了如何 register COM servers the right way 之后,我仍然有兴趣了解,为什么我的 MSI 软件包以前可以工作。换句话说:Windows XP 之后的关键变化是什么?
...同时我还检查了当我 运行 作为管理员时 MSI 是否工作...
我在阅读 WiX 工具集文档时发现,CustomAction
有一个属性 Impersonate
,它控制 CA 是否以提升的权限执行:
指的是msidbCustomActionTypeNoImpersonate
flag in the Type
field of the CustomAction
Table。我在 MSI 中观察到的值 1122
被反编译为:
- 1024(标志):msidbCustomActionTypeInScript,或者,延迟执行,安装脚本运行秒
- 64(标志):msidbCustomActionTypeContinue,或者,忽略退出代码并继续
- 34:Custom Action Type 34,或者,通过命令行启动可执行文件
我用来解决 "fix" 问题的快速方法是,在 CA 类型中启用 msidbCustomActionTypeNoImpersonate
标志 (2048
)(在 WiX 中这将是 Impersonate="no"
).
翻译成我的 MakeMsi 脚本,我不得不 使用 Type
中的 System
属性ExeCa
command 使自注册工作 和以前一样:
Type="Deferred Sync AnyRc System"
我完全知道这只是一种变通方法,因为 运行 为(取消)注册一个 COM 服务器是危险的。所以 should be preferred: manage COM related static information via registry entries in the MSI. But sometimes you need a fast solution, and sometimes there is no other option, see .
第二节提到的解决方案
我有一个 32 位应用程序的安装程序包(使用 MakeMsi 构建,最初是为 Windows XP 构建的,从那时起就简单地维护了),但无法在现代(64 位)上注册 COM 服务器Windows 系统(7、8、10)。这是我在尝试正常安装 MSI 时看到的:
Application Error
Exception EOleSysError in module xyz at 000F0B01. Error accessing the OLE registry.
如果我将 MSI 置于 兼容模式 Windows 的先前版本,COM 服务器注册成功。由于 “它正在工作” 不知何故,到目前为止我没有投入太多时间来探索原因。但最后,我厌倦了一次又一次地记住我们的客户(有时也是我)这个先决条件,所以我想解决这个问题。
注册(和注销)是通过 CustomActions 完成的,正如我使用 Orca 所见:
"[INSTALLDIR.MYAPP]\placeholder.exe" -regserver
"[INSTALLDIR.MYAPP]\placeholder.exe" -unregserver
对于这些条目中的每一个,Type
是 1122
并且 Source
是 INSTALLDIR.MYAPP
。
我可以想象在安装过程中 COM 服务器是在权限不足的情况下启动的,但是安装程序 运行 不是自动具有管理员权限吗?我的意思是,当我(作为标准用户)通过双击启动安装程序时,它会在实际安装发生之前 显示 UAC 提示符。为什么 COM 服务器没有 运行 注册和注销的提升权限?令人困惑...
我应该如何更改我的 MSI 以使 Windows 安装程序成功处理它?
我假设您知道问题出在您作为自定义操作 运行ning 的可执行文件中,而不是 Windows 安装程序中的任何内容。这意味着问题将出在可执行文件中的代码,它可能是旧的并且与后来的 OS 版本不兼容。您需要查看代码以了解不受支持的功能。
许多安装不需要自行注册。该数据是所有静态数据,可以提取一次并包含在注册表项和其他 COM class 表中的 MSI 文件中。这意味着在安装过程中根本不需要 运行 代码。
在学习了如何 register COM servers the right way 之后,我仍然有兴趣了解,为什么我的 MSI 软件包以前可以工作。换句话说:Windows XP 之后的关键变化是什么?
...同时我还检查了当我 运行 作为管理员时 MSI 是否工作...
我在阅读 WiX 工具集文档时发现,CustomAction
有一个属性 Impersonate
,它控制 CA 是否以提升的权限执行:
指的是msidbCustomActionTypeNoImpersonate
flag in the Type
field of the CustomAction
Table。我在 MSI 中观察到的值 1122
被反编译为:
- 1024(标志):msidbCustomActionTypeInScript,或者,延迟执行,安装脚本运行秒
- 64(标志):msidbCustomActionTypeContinue,或者,忽略退出代码并继续
- 34:Custom Action Type 34,或者,通过命令行启动可执行文件
我用来解决 "fix" 问题的快速方法是,在 CA 类型中启用 msidbCustomActionTypeNoImpersonate
标志 (2048
)(在 WiX 中这将是 Impersonate="no"
).
翻译成我的 MakeMsi 脚本,我不得不 使用 Type
中的 System
属性ExeCa
command 使自注册工作 和以前一样:
Type="Deferred Sync AnyRc System"
我完全知道这只是一种变通方法,因为 运行 为(取消)注册一个 COM 服务器是危险的。所以