为什么WiX不允许我在HKLM中设置非广告快捷方式的KeyPath?

时间:2016-05-14 19:53:59

标签: wix windows-installer

我正在尝试为每台计算机应用程序生成安装程序。这是我的组成部分:

<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的每用户和每台机器数据。

所以我真的很想知道如何避免任何这些错误/警告,而不是将所有内容安装到用户配置文件中。

2 个答案:

答案 0 :(得分:3)

我已将问题缩小到以下事实:快捷DirectoryMenuFolder(我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 machineWhy do we get an ICE57 error for non advertised shortcuts in per machine installations?

中有更多讨论