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

Dra*_*vuk 5 windows-installer wix

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

<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>
Run Code Online (Sandbox Code Playgroud)

WiX吐出以下内容:

错误ICE43:组件ProductComponent具有未发布的快捷方式。它的KeyPath注册表项应属于HKCU。

I can't understand why it requires a per-user KeyPath for what I intend to be a per-machine component. Would this key not be left behind during uninstall performed by another user? Or its absence result in a duplicate during repair?

似乎如此,将其更改为HKCU后,我仍然收到以下信息:

警告ICE57:组件'ProductComponent'具有按用户和按计算机的数据,并带有HKCU注册表键路径。

因此,我对如何避免在将所有内容都安装到用户配置文件中时避免任何这些错误/警告感到困惑。

Dra*_*vuk 7

我已将问题范围缩小到以下事实:快捷方式DirectoryMenuFolder我的文件夹位于ProgramMenuFolder)被视为用户配置文件目录(与ALLUSERS/InstallScope属性无关),因此似乎反对将其KeyPath设置在 HKLM 中。我从以下事实推断出这一点: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>
Run Code Online (Sandbox Code Playgroud)

以上需要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>
Run Code Online (Sandbox Code Playgroud)


bra*_*drg 6

严格来说,抛出这些错误的不是 WIX,而是Microsoft Windows Installer Internal Consistency Evaluators。WIX 在构建 MSI 期间运行所有 ICE,如果有任何失败,则会引发错误。总的来说,这是一件好事,因为它在构建阶段消除了 MSI 数据库中的许多潜在错误。

您可以通过使用 HKMU 作为注册表根来消除ICE43错误。HKMU 是 WIX 用来将值 -1 放入Windows 安装程序数据库注册表列中的特殊常量。这会导致 Windows Installer 将注册表项放在每台机器安装的 HKLM 和每用户安装的 HKCU 中。

迄今为止,我发现无法在不将快捷方式移动到其自己的组件并使用 HKCU 作为注册表根的情况下,修复每台机器安装中非广告快捷方式的ICE57错误。但是,如果用户 A安装产品而用户 B删除产品,则以这种方式编写的安装程序数据库可能会在用户 A 的注册表配置单元中留下注册表项。

长期以来,我一直认为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>
Run Code Online (Sandbox Code Playgroud)

查看上面的示例,ShortcutComponentis的目录MenuFolder通常来自ProgramMenuFolder.

Windows Installer 将重定向ProgramMenuFolder到每台计算机安装中的“所有用户”菜单文件夹,或每用户安装中的“当前用户”菜单文件夹。有关如何根据安装是按机器还是按用户重定向文件夹的详细信息,请参阅安装上下文

类似地,注册表根 HKMU 应该在每台机器安装中重定向到 HKLM,在每用户安装中重定向到 HKCU。

在每台机器和每用户方案中,快捷方式和注册表设置的安装位置是一致的。尽管有明显的一致性,您仍然会收到 ICE57 错误。这意味着 ICE57 在这种情况下会产生误报。

有更多的讨论维克斯创建每台机器的所有用户的非广告的快捷方式/我们为什么在每台机器上安装获得非广告的快捷方式的ICE57错误?