我正在尝试为每台计算机应用程序生成安装程序。这是我的组成部分:
<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吐出以下内容:
错误ICE43:组件ProductComponent具有未公布的快捷方式。它的KeyPath注册表密钥应属于HKCU。
我无法理解为什么它需要每用户KeyPath才能成为每台机器组件。在其他用户执行卸载期间,此密钥是否会被遗忘?或者它的缺席导致修复期间出现重复?
似乎是这样,因为在将其改为HKCU后,我仍然收到以下内容:
警告ICE57:组件'ProductComponent'具有HKCU Registry KeyPath的每用户和每台机器数据。
所以我真的很想知道如何避免任何这些错误/警告,而不是将所有内容安装到用户配置文件中。
答案 0 :(得分:3)
我已将问题缩小到以下事实:快捷Directory
,MenuFolder
(我ProgramMenuFolder
下的文件夹)被视为用户个人资料目录(无论{ {1}} / ALLUSERS
属性),因此似乎反对在HKLM中设置InstallScope
。我将此问题推断为KeyPath
以及所有错误和警告在将此属性设置为Error ICE43
(我InstallFolder
下的文件夹)时消失的事实。
我已经找到了两个可行的选择:
ProgramFilesFolder
以上要求禁用<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"
答案 1 :(得分:3)
严格来说,不是WIX抛出这些错误而是Microsoft Windows Installer Internal Consistency Evaluators。 WIX在构建MSI期间运行所有ICE,如果失败则抛出错误。总的来说,这是一件好事,因为它在构建阶段消除了MSI数据库中的许多潜在错误。
使用HKMU作为注册表根目录,可以消除ICE43错误。 HKMU是WIX使用的特殊常量,用于将值-1置于Windows Installer数据库的Registry Table的 Root 列中。这会导致Windows Installer在每个计算机上安装HKLM中放置注册表项,并在每个用户安装上放置HKCU。
到目前为止,我还没有找到修复每台机器安装中未公布的快捷方式的ICE57错误的方法,而无需将快捷方式移动到自己的组件并使用HKCU作为注册表根目录。但是,如果用户A 安装产品并且用户B >用户B,则以这种方式编写的安装程序数据库可以在用户A 注册表配置单元中留下注册表项。 em>删除产品。
我一直认为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 Installer会将ProgramMenuFolder
重定向到每台计算机安装中的所有用户菜单文件夹,或每个用户中的当前用户菜单文件夹安装。有关如何重定向文件夹的详细信息,请参阅Installation Context,具体取决于安装是按计算机还是按用户安装。
同样,注册机构根HKMU应在每台机器安装中重定向到HKLM,并在每用户安装中重定向到HKCU。
在每台计算机和每用户方案中,快捷方式和注册表设置的安装位置是一致的。尽管表面上看具有明显的一致性,但仍然会出现ICE57错误。这意味着ICE57在这种情况下会产生误报错误。
Wix create non advertised shortcut for all users / per machine和Why do we get an ICE57 error for non advertised shortcuts in per machine installations?
中有更多讨论