(WiX) 适用于全局安装的程序文件快捷方式

23

参考这里的示例,我向ProgramMenuFolder添加了一个启动我的应用程序的快捷方式。 (我的代码实际上更简单,因为我不需要额外的文件夹。)

<DirectoryRef Id='ProgramMenuFolder'>
  <Component Id='cmpStartMenuShortcut'
             Guid='MY GUID HERE'>
    <Shortcut Id='StartMenuShortcut'
              Name='$(var.ProductName)'
              Icon='MainIcon.ico'
              Description='$(var.ProductName)'
              Target='[ClientDir]myapp.exe'
              WorkingDirectory='ClientDir'/>
    <RegistryValue Action='write' Type='integer' Root='HKCU'
                   Key='Software\Company\Product Name'
                   Name='installed' Value='1' KeyPath='yes'/>
  </Component>
</DirectoryRef>

由于我的安装是针对整个计算机的(ALLUSERS=1,Package / @InstallPrivileges ='elevated'和@InstallScope ='perMachine'),ProgramMenuFolder是该计算机上所有用户的文件夹。

我的问题与注册表值有关。 我的理解是,它仅需要为包含快捷方式的组件提供KeyPath。 该示例使用HKCU,这是每个用户的位置。

在将每台计算机组件的KeyPath设置为每个用户值时,这不是错误吗?

如果计算机有两个管理员,管理员#1安装产品,管理员#2尝试修复,则Windows Installer将看不到注册表值,并认为快捷方式丢失,因此会安装重复项,对吗?

因此,我尝试将RegistryValue / @Root更改为HKLM,但然后WiX会出现以下错误:

error LGHT0204:ICE38:组件cmpStartMenuShortcut安装到用户配置文件中。 它的KeyPath注册表键必须位于HKCU下。

error LGHT0204:ICE43:组件cmpStartMenuShortcut具有非广告快捷方式。 它的KeyPath注册表键应该位于HKCU下。

error LGHT0204:ICE57:组件'cmpStartMenuShortcut'具有既有每个用户又有每台计算机数据的每台计算机KeyPath。

我不明白为什么键必须在HKCU下。

2个回答

14
那种快捷方式的样式是针对可能现在或调用时未安装的目标而设计的。它创建了经典的.lnk快捷方式文件。它适用于指向目标的快捷方式,这些目标不是您的安装程序负责的,但可能对您产品的用户有用(例如cmd.exe)。
或者,对于您正在安装或广告的目标的快捷方式将在目标取消广告(产品卸载)时被卸载。例如,WiX安装了一个名为WiX Documentation的wix.chm快捷方式。广告快捷方式的Shortcut元素可以成为File元素的子元素。
这里是一个手写的示例:
<Component Id="ProductComponent">
   <File Source="$(var.ConsoleApplication1.TargetPath)" KeyPath="yes">
     <Shortcut Id="$(var.ConsoleApplication1.TargetName)Shortcut" 
               Name="$(var.ConsoleApplication1.TargetName)" 
               Advertise="yes"
               Description="Starts $(var.ConsoleApplication1.TargetName)"
               Directory="ProgramMenuFolder" />
   </File>
</Component>

要将快捷方式元素插入到Heat的输出中,请将其传递给XSL转换的路径。代码片段:
<xsl:template match="wix:File[contains(@Source,'\myapp.exe')]">
  <xsl:copy-of select="." />
  <Shortcut Id='StartMenuShortcut'
          Advertise="yes"
          Name='$(var.ProductName)'
          Icon='MainIcon.ico'
          Description='$(var.ProductName)'
          WorkingDirectory='ClientDir'/>
</xsl:template>

2
谢谢。这个解决方案对我来说似乎是有效的。当我开始使用WiX时,我不知道我将不得不学习XSLT。 - Adrian McCarthy
6
为什么未广告的快捷方式不能将其KeyPath写入HKLM,而未广告的快捷方式需要一个注册表 KeyPath,但广告快捷方式则不需要,你并没有真正回答这个问题。 - Drazen Bjelovuk
这个答案与我认为的问题有些不相关,正如@DrazenBjelovuk所提到的那样,它并没有完全解释或涵盖为什么常规(非广告)快捷方式(我想大多数应用程序都在使用)会引起问题中引用的错误。 - Armen Michaeli

0
我建议的做法是按照你说的创建文件夹,但不要直接将快捷方式放在文件夹下面。相反,在包含文件的组件下创建一个快捷方式元素。您可以使用Directory属性指定想要快捷方式出现的位置。

谢谢您的建议。不幸的是,持有文件的组件是由热生成的(并且定期重新生成),因此使用该方法并不实际。我真的很想了解为什么将每台机器位置用作每台机器组件的KeyPath会出错。 - Adrian McCarthy
1
这里的主要问题是整个开始菜单是按用户分的。您所引用的用户是整个用户组,但在Windows Installer中仍被视为一个用户。 - Christopher B. Adkins
开始菜单不是用户特定和计算机通用元素的混合视图吗?当我以计算机级别运行我的安装程序时,快捷方式会添加到所有用户\开始菜单\程序中,而不是<user>\开始菜单\程序。 - Adrian McCarthy
所有用户在Windows Installer的视角下都被视为一个用户。它只是另一个用户配置文件。如果更容易理解,可以使用S-1-1-0 SID。 - Christopher B. Adkins
2
但是HKCU注册表值将对应于安装用户,而不是S-1-1-0 SID。如果另一个管理员进来尝试修复安装,它将无法找到现有的HKCU KeyPath,而是会创建一个冗余的快捷方式。 - Adrian McCarthy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接