为什么 WiX 不允许我在 HKLM 中设置非广告快捷方式的 KeyPath?
Why won't WiX let me set the KeyPath of a non-advertised shortcut in HKLM?
我正在尝试为每台机器的应用程序生成安装程序。这是我的组件:
<Component Id="ProductComponent" Directory="InstallFolder" Guid="{MY_GUID}">
<File Id="ProductComponent" Source="$(var.MyApp.TargetPath)">
<Shortcut Id="StartMenuShortcut"
Name="MyApp"
Description="App Description"
Directory="MenuFolder"
WorkingDirectory="InstallFolder"
Icon="icon.ico" />
</File>
<RemoveFolder Id="RemoveMenuFolder" Directory="MenuFolder" On="uninstall" />
<RegistryValue Root="HKLM" Key="Software\Microsoft\MyApp" Name="installed" Type="integer" Value="1" KeyPath="yes"/>
</Component>
WiX 吐出以下内容:
Error ICE43: Component ProductComponent has non-advertised shortcuts. It's KeyPath registry key should fall under HKCU.
我不明白为什么它需要一个每个用户的 KeyPath 来实现我打算成为每个机器的组件。在另一个用户执行的卸载过程中不会留下这个密钥吗?或者它的缺失导致修复期间出现重复?
好像是,换成HKCU后,还是收到:
Warning ICE57: Component 'ProductComponent' has both per-user and per-machine data with an HKCU Registry KeyPath.
所以我真的不知道如何避免这些 errors/warnings 除了将所有内容都安装到用户配置文件之外。
我已将问题缩小到以下事实:快捷方式 Directory
、MenuFolder
(我的文件夹在 ProgramMenuFolder
下)被视为用户配置文件目录(无论ALLUSERS
/InstallScope
属性),因此似乎反对在 HKLM 中设置其 KeyPath
。我从以下事实推断出这一点:当简单地将此属性设置为 InstallFolder
(我的文件夹在 ProgramFilesFolder
下)时,Error ICE43
以及所有错误和警告都会消失。
我得出了两个可行的选择:
将文件(每台机器)和非广告快捷方式(每用户)作为单独的组件安装
<Component Id="ProductComponent" Directory="InstallFolder" Guid="{MY_GUID}">
<File Id="ProductComponent" Source="$(var.MyApp.TargetPath)" KeyPath="yes">
</Component>
<Component Id="ShortcutComponent" Directory="MenuFolder" Guid="{MY_GUID}">
<Shortcut Id="StartMenuShortcut"
Name="MyApp"
Description="App Description"
Target="[#ProductComponent]"
WorkingDirectory="InstallFolder"
Icon="icon.ico" />
<RemoveFolder Id="RemoveMenuFolder" On="uninstall" />
<RegistryValue Root="HKCU" Key="Software\Microsoft\MyApp" Name="installed" Type="integer" Value="1" KeyPath="yes"/>
</Component>
以上要求 ALLUSER
属性 禁用 (InstallScope="perUser"
) 以防止不同的用户卸载(导致注册表残留)。
安装文件和公布的快捷方式作为每台机器的组件
<Component Id="ProductComponent" Directory="InstallFolder" Guid="{MY_GUID}">
<File Id="ProductComponent" Source="$(var.MyApp.TargetPath)" KeyPath="yes">
<Shortcut Id="StartMenuShortcut"
Name="MyApp"
Description="App Description"
Advertise="yes"
Directory="MenuFolder"
WorkingDirectory="InstallFolder"
Icon="icon.ico" />
</File>
<RemoveFolder Id="RemoveMenuFolder" Directory="MenuFolder" On="uninstall" />
</Component>
严格来说,不是 WIX 抛出了这些错误,而是 Microsoft Windows Installer Internal Consistency Evaluators。 WIX 在构建 MSI 期间运行所有 ICE,并在任何失败时抛出错误。总的来说,这是一件好事,因为它在构建阶段消除了 MSI 数据库中的许多潜在错误。
您可以创建 Windows 安装程序数据库的 ICE43 error go away by using HKMU as the registry root. HKMU is a special constant used by WIX to put the value -1 in the Root column of the Registry Table。这会导致 Windows 安装程序将注册表项放置在每台机器安装的 HKLM 和每用户安装的 HKCU 中。
到目前为止,如果不将快捷方式移动到其自己的组件并使用 HKCU 作为注册表根目录,我无法修复每台机器安装中非广告快捷方式的 ICE57 错误。但是,如果 用户 A 安装了产品并且 用户 B 删除了产品。
我一直觉得 ICE57 在检查每台机器安装中未公布的快捷方式时会产生误报错误。这很难 100% 肯定地证明,因为我们无法访问 ICE57 背后的逻辑。
在这种情况下,我倾向于为 EXE 和快捷方式使用单独的组件。在快捷方式的注册表值中使用注册表根目录中的HKMU并在WIX工具设置中抑制ICE57:
<Component Id="ProductComponent" Directory="InstallFolder" Guid="{MY_GUID}">
<File Id="ProductComponent" Source="$(var.MyApp.TargetPath)" KeyPath="yes">
</Component>
<Component Id="ShortcutComponent" Directory="MenuFolder" Guid="{MY_GUID}">
<Shortcut Id="StartMenuShortcut"
Name="MyApp"
Description="App Description"
Target="[#ProductComponent]"
WorkingDirectory="InstallFolder"
Icon="icon.ico" />
<RemoveFolder Id="RemoveMenuFolder" On="uninstall" />
<RegistryValue Root="HKMU" <!-- Resolves to HKLM on per machine installs -->
Key="Software\Microsoft\MyApp"
Name="installed"
Type="integer"
Value="1"
KeyPath="yes"/>
</Component>
看上面的例子,ShortcutComponent
的目录是MenuFolder
,通常是从ProgramMenuFolder
派生的。
Windows 安装程序将 ProgramMenuFolder
重定向到每台机器安装中的 All Users 菜单文件夹,或 Current User 每个用户安装中的菜单文件夹。有关如何根据安装是每台机器还是每用户重定向文件夹的详细信息,请参阅 Installation Context。
同样,注册表根 HKMU 应该在每台机器安装中重定向到 HKLM,在每用户安装中重定向到 HKCU。
在每台机器和每用户方案中,快捷方式和注册表设置的安装位置是一致的。尽管表面上一致,您仍然会收到 ICE57 错误。这意味着 ICE57 在这种情况下产生误报错误。
Wix create non advertised shortcut for all users / per machine and Why do we get an ICE57 error for non advertised shortcuts in per machine installations?
中有更多讨论
我正在尝试为每台机器的应用程序生成安装程序。这是我的组件:
<Component Id="ProductComponent" Directory="InstallFolder" Guid="{MY_GUID}">
<File Id="ProductComponent" Source="$(var.MyApp.TargetPath)">
<Shortcut Id="StartMenuShortcut"
Name="MyApp"
Description="App Description"
Directory="MenuFolder"
WorkingDirectory="InstallFolder"
Icon="icon.ico" />
</File>
<RemoveFolder Id="RemoveMenuFolder" Directory="MenuFolder" On="uninstall" />
<RegistryValue Root="HKLM" Key="Software\Microsoft\MyApp" Name="installed" Type="integer" Value="1" KeyPath="yes"/>
</Component>
WiX 吐出以下内容:
Error ICE43: Component ProductComponent has non-advertised shortcuts. It's KeyPath registry key should fall under HKCU.
我不明白为什么它需要一个每个用户的 KeyPath 来实现我打算成为每个机器的组件。在另一个用户执行的卸载过程中不会留下这个密钥吗?或者它的缺失导致修复期间出现重复?
好像是,换成HKCU后,还是收到:
Warning ICE57: Component 'ProductComponent' has both per-user and per-machine data with an HKCU Registry KeyPath.
所以我真的不知道如何避免这些 errors/warnings 除了将所有内容都安装到用户配置文件之外。
我已将问题缩小到以下事实:快捷方式 Directory
、MenuFolder
(我的文件夹在 ProgramMenuFolder
下)被视为用户配置文件目录(无论ALLUSERS
/InstallScope
属性),因此似乎反对在 HKLM 中设置其 KeyPath
。我从以下事实推断出这一点:当简单地将此属性设置为 InstallFolder
(我的文件夹在 ProgramFilesFolder
下)时,Error ICE43
以及所有错误和警告都会消失。
我得出了两个可行的选择:
将文件(每台机器)和非广告快捷方式(每用户)作为单独的组件安装
<Component Id="ProductComponent" Directory="InstallFolder" Guid="{MY_GUID}">
<File Id="ProductComponent" Source="$(var.MyApp.TargetPath)" KeyPath="yes">
</Component>
<Component Id="ShortcutComponent" Directory="MenuFolder" Guid="{MY_GUID}">
<Shortcut Id="StartMenuShortcut"
Name="MyApp"
Description="App Description"
Target="[#ProductComponent]"
WorkingDirectory="InstallFolder"
Icon="icon.ico" />
<RemoveFolder Id="RemoveMenuFolder" On="uninstall" />
<RegistryValue Root="HKCU" Key="Software\Microsoft\MyApp" Name="installed" Type="integer" Value="1" KeyPath="yes"/>
</Component>
以上要求 ALLUSER
属性 禁用 (InstallScope="perUser"
) 以防止不同的用户卸载(导致注册表残留)。
安装文件和公布的快捷方式作为每台机器的组件
<Component Id="ProductComponent" Directory="InstallFolder" Guid="{MY_GUID}">
<File Id="ProductComponent" Source="$(var.MyApp.TargetPath)" KeyPath="yes">
<Shortcut Id="StartMenuShortcut"
Name="MyApp"
Description="App Description"
Advertise="yes"
Directory="MenuFolder"
WorkingDirectory="InstallFolder"
Icon="icon.ico" />
</File>
<RemoveFolder Id="RemoveMenuFolder" Directory="MenuFolder" On="uninstall" />
</Component>
严格来说,不是 WIX 抛出了这些错误,而是 Microsoft Windows Installer Internal Consistency Evaluators。 WIX 在构建 MSI 期间运行所有 ICE,并在任何失败时抛出错误。总的来说,这是一件好事,因为它在构建阶段消除了 MSI 数据库中的许多潜在错误。
您可以创建 Windows 安装程序数据库的 ICE43 error go away by using HKMU as the registry root. HKMU is a special constant used by WIX to put the value -1 in the Root column of the Registry Table。这会导致 Windows 安装程序将注册表项放置在每台机器安装的 HKLM 和每用户安装的 HKCU 中。
到目前为止,如果不将快捷方式移动到其自己的组件并使用 HKCU 作为注册表根目录,我无法修复每台机器安装中非广告快捷方式的 ICE57 错误。但是,如果 用户 A 安装了产品并且 用户 B 删除了产品。
我一直觉得 ICE57 在检查每台机器安装中未公布的快捷方式时会产生误报错误。这很难 100% 肯定地证明,因为我们无法访问 ICE57 背后的逻辑。
在这种情况下,我倾向于为 EXE 和快捷方式使用单独的组件。在快捷方式的注册表值中使用注册表根目录中的HKMU并在WIX工具设置中抑制ICE57:
<Component Id="ProductComponent" Directory="InstallFolder" Guid="{MY_GUID}">
<File Id="ProductComponent" Source="$(var.MyApp.TargetPath)" KeyPath="yes">
</Component>
<Component Id="ShortcutComponent" Directory="MenuFolder" Guid="{MY_GUID}">
<Shortcut Id="StartMenuShortcut"
Name="MyApp"
Description="App Description"
Target="[#ProductComponent]"
WorkingDirectory="InstallFolder"
Icon="icon.ico" />
<RemoveFolder Id="RemoveMenuFolder" On="uninstall" />
<RegistryValue Root="HKMU" <!-- Resolves to HKLM on per machine installs -->
Key="Software\Microsoft\MyApp"
Name="installed"
Type="integer"
Value="1"
KeyPath="yes"/>
</Component>
看上面的例子,ShortcutComponent
的目录是MenuFolder
,通常是从ProgramMenuFolder
派生的。
Windows 安装程序将 ProgramMenuFolder
重定向到每台机器安装中的 All Users 菜单文件夹,或 Current User 每个用户安装中的菜单文件夹。有关如何根据安装是每台机器还是每用户重定向文件夹的详细信息,请参阅 Installation Context。
同样,注册表根 HKMU 应该在每台机器安装中重定向到 HKLM,在每用户安装中重定向到 HKCU。
在每台机器和每用户方案中,快捷方式和注册表设置的安装位置是一致的。尽管表面上一致,您仍然会收到 ICE57 错误。这意味着 ICE57 在这种情况下产生误报错误。
Wix create non advertised shortcut for all users / per machine and Why do we get an ICE57 error for non advertised shortcuts in per machine installations?
中有更多讨论