Wix 为所有用户/每台机器创建非广告快捷方式

Posted

技术标签:

【中文标题】Wix 为所有用户/每台机器创建非广告快捷方式【英文标题】:Wix create non advertised shortcut for all users / per machine 【发布时间】:2011-01-04 17:16:21 【问题描述】:

在 WIX 中,如何在 allusers 配置文件中创建非广告快捷方式?到目前为止,我只能通过宣传的捷径来实现这一点。我更喜欢非广告快捷方式,因为您可以转到快捷方式的属性并使用“查找目标”。

在我看到的教程中,使用注册表值作为快捷方式的键路径。问题是他们使用 HKCU 作为根。当使用 HKCU 并且另一个用户卸载该程序(因为它是为所有用户安装的)时,注册表项被留下。当我使用 HKMU 作为根时,我得到一个 ICE57 错误,但是当另一个用户卸载程序时,密钥被删除。尽管 HKMU 似乎表现正确(每个用户与所有用户),但我似乎被推向使用 HKCU。

当我尝试创建非广告快捷方式时,我遇到了各种 ICE 错误,例如 ICE38、ICE43 或 ICE 57。我看到的大多数文章都建议“忽略 ice 错误”。必须有一种方法可以创建非广告快捷方式,而不会产生 ICE 错误。

请发布一个工作示例的示例代码。

【问题讨论】:

【参考方案1】:

看看 Alex Shevchuk 的 From MSI to WiX, Part 10 - Shortcuts。

或者 Rob Menching 的博文How to create an uninstall shortcut (and pass all the ICE validation).

基本上 ICE57 相当烦人......但这是我用于桌面快捷方式的(似乎正在工作)代码:)

<Component Id="DesktopShortcut" Directory="APPLICATIONFOLDER" Guid="*">
    <RegistryValue Id="RegShortcutDesktop" Root="HKCU" Key="SOFTWARE\My App\1.0\settings" Name="DesktopSC" Value="1" Type="integer" KeyPath="yes" />
    <Shortcut Id="desktopSc" Target="[APPLICATIONFOLDER]MyApp.exe" Directory="DesktopFolder" Name="My Applications" Icon="myapp.ico" IconIndex="0" WorkingDirectory="APPLICATIONFOLDER" Advertise="no"/>
    <RemoveFolder Id="RemoveShortcutFolder" On="uninstall" />
    <Condition>DT_SHORTCUT=1</Condition>
</Component>

【讨论】:

您的示例使用“HKCU”作为密钥路径。如果一个用户安装了该应用程序,而另一个用户删除了该应用程序,则注册表项将保留在后面。发布的第一个链接使用 HKCU 作为注册表项。第二个使用文件作为产生 ICE43 和 ICE57 错误的密钥路径。 注册表项,是的。但是不是快捷方式本身:)【参考方案2】:

如果回答我自己的问题不礼貌,请见谅。

最近我偶然发现了DISABLEADVTSHORTCUTS property 上的信息。我创建了一个带有广告快捷方式的安装,并将 DISABLEADVTSHORTCUTS 属性设置为 1,这会产生非广告快捷方式。这绕过了ICE43 errors,因为广告的快捷方式可以使用文件作为键路径。因为 DISABLEADVTSHORTCUTS 已设置,Windows Installer 将用常规快捷方式替换这些公布的快捷方式。

我将Package Element's InstallScope 属性设置为“perMachine”。这会将 ALLUSERS 属性设置为 1。ProgramMenuFolder 和 DesktopFolder 的值将解析为所有用户配置文件。

对于在 ProgramMenuFolder 下创建的文件夹,有一个 RemoveFolder 和 RegistryValue 元素。我见过的示例(ex1、ex2)使用 HKCU 作为 RegistryValue 的根。我将此根更改为 HKMU,根据 ALLUSERS 的值解析为 HKCU 或 HKLM。

简而言之,将 DISABLEADVTSHORTCUTS 设置为 1,您的广告快捷方式不会产生 ICE 错误,但在安装时会转换为非广告快捷方式。具有根 HKMU 的 RegistryValue 对于 KeyPath 来说是可以的,只要它不是非广告快捷方式的 keypath。

<?xml version="1.0" encoding="utf-8"?>
<!-- This example is based on SampleFirst by Gábor DEÁK JAHN, Tramontána:
        http://www.tramontana.co.hu/wix/lesson1.php#1.3
    Original SampleFirst:
        http://www.tramontana.co.hu/wix/download.php?file=samples/samplefirst.zip&type=application/zip -->
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
    <Product Name="Foobar 1.0" Id="YOURGUID-21F1-4026-ABD2-7CC7F8CE4D18" UpgradeCode="YOURGUID-AFA4-46C6-94AA-EEE3D104F903" Language="1033" Codepage="1252" Version="1.0.0" Manufacturer="Acme Ltd.">
        <Package Id="*" Keywords="Installer" Description="Acme's Foobar 1.0 Installer" Comments="Foobar is a registered trademark of Acme Ltd." Manufacturer="Acme Ltd." InstallerVersion="100" Languages="1033" Compressed="yes" SummaryCodepage="1252" InstallScope="perMachine" />
        <Media Id="1" Cabinet="Sample.cab" EmbedCab="yes" DiskPrompt="CD-ROM #1" />
        <Property Id="DiskPrompt" Value="Acme's Foobar 1.0 Installation [1]" />
        <Property Id="DISABLEADVTSHORTCUTS" Value="1" />
        <Directory Id="TARGETDIR" Name="SourceDir">
            <Directory Id="ProgramFilesFolder" Name="PFiles">
                <Directory Id="Acme" Name="Acme">
                    <Directory Id="INSTALLDIR" Name="Foobar 1.0">
                        <Component Id="MainExecutable" Guid="YOURGUID-3E4F-47A2-86F1-F3162E9C4798">
                            <File Id="FoobarEXE" Name="FoobarAppl10.exe" DiskId="1" Source="FoobarAppl10.exe" KeyPath="yes">
                                <Shortcut Id="startmenuFoobar10" Directory="ProgramMenuDir" Name="Foobar 1.0" WorkingDirectory="INSTALLDIR" Icon="Foobar10.exe" IconIndex="0" Advertise="yes" />
                                <Shortcut Id="desktopFoobar10" Directory="DesktopFolder" Name="Foobar 1.0" WorkingDirectory="INSTALLDIR" Icon="Foobar10.exe" IconIndex="0" Advertise="yes" />
                            </File>
                        </Component>
                        <Component Id="HelperLibrary" Guid="YOURGUID-C7DA-4C02-A2F0-A6E089FC0CF3">
                            <File Id="HelperDLL" Name="Helper.dll" DiskId="1" Source="Helper.dll" KeyPath="yes" />
                        </Component>
                        <Component Id="Manual" Guid="YOURGUID-FF92-4BF4-A322-819A3B2265A0">
                            <File Id="Manual" Name="Manual.pdf" DiskId="1" Source="Manual.pdf" KeyPath="yes">
                                <Shortcut Id="startmenuManual" Directory="ProgramMenuDir" Name="Instruction Manual" Advertise="yes" />
                            </File>
                        </Component>
                    </Directory>
                </Directory>
            </Directory>
            <Directory Id="ProgramMenuFolder" Name="Programs">
                <Directory Id="ProgramMenuDir" Name="Foobar 1.0">
                    <Component Id="ProgramMenuDir" Guid="YOURGUID-D1C2-4D76-BA46-C6FA79862E77">
                        <RemoveFolder Id="ProgramMenuDir" On="uninstall" />
                        <RegistryValue Root="HKMU" Key="Software\[Manufacturer]\[ProductName]" Type="string" Value="" KeyPath="yes" />
                    </Component>
                </Directory>
            </Directory>
            <Directory Id="DesktopFolder" Name="Desktop" />
        </Directory>
        <Feature Id="Complete" Level="1">
            <ComponentRef Id="MainExecutable" />
            <ComponentRef Id="HelperLibrary" />
            <ComponentRef Id="Manual" />
            <ComponentRef Id="ProgramMenuDir" />
        </Feature>
        <Icon Id="Foobar10.exe" SourceFile="FoobarAppl10.exe" />
    </Product>
</Wix>

【讨论】:

您的答案中的详细信息非常好。我发现这非常有帮助,因为我一直在阅读 WiX 文档和示例。谢谢! 很好的答案。但是假设我在一个单独的组件中有一个桌面快捷方式(因为我有条件地安装它)。 IIUC 不能宣传此类捷径。如果我尝试添加 Advertise="yes",即使使用 DISABLEADVTSHORTCUTS,我也会收到错误 CNDL0035。你能看到用 HKMU 注册表项创建这种快捷方式的方法吗? 如果您找到了一个好的解决方案,回答您自己的问题一点也不坏,我非常感谢您这样做 - 并且提供了一个很好的启动答案。 +1! 不要将图标引用到可执行文件。图标被复制到特殊目录(Windows\Installer\GUID),快捷方式将使用该位置的图标(即不是来自INSTALLDIR中的可执行文件),因此最好使用单独的图标文件。 非常感谢。我花了几个小时解决这个问题。不知道 DISABLEADVTSHORTCUTS。【参考方案3】:

虽然这篇文章相当陈旧,但它包含非常有用的信息并且看起来仍然活跃。我想指出,一般来说,您的快捷方式不需要虚拟注册表项! AFAIK 这是 WiX 教程,不是 MSI 或认证要求。这是一个没有 reg 键的示例:

<Fragment Id="Folders">
  <Directory Id="TARGETDIR" Name="SourceDir">
    <Directory Id="ProgramFilesFolder">
      <Directory Id="INSTALLFOLDER" Name="MyApp">
      </Directory>
    </Directory>
    <Directory Id="ProgramMenuFolder">
      <Directory Id="MyAppStartMenuDir" Name="MyApp"/>
    </Directory>
  </Directory>
</Fragment>
<Fragment Id="Components">
  <Component Id="MyAppComp" Directory="INSTALLFOLDER" ...>
    <!--The advertise flag below is to bypass ICE errors in WiX, the actual shortcut will not be advertises if those are disabled globally with DISABLEADVTSHORTCUTS-->
    <File ..." KeyPath="yes">
      <Shortcut Id="MyAppStartMenuLink" Directory="MyAppStartMenuDir" Advertise="yes" ... />
    </File>
    <RemoveFolder Id="StartMenuDirRemoved" Directory="MyAppStartMenuDir" On="uninstall" />
  </Component>
</Fragment>

请注意,这会将您的快捷方式与可执行文件放在一个组件中。如果这让您感到困扰,请使用虚拟注册表项(如在很好解释的接受的自我答案中)。

【讨论】:

记得在 Product 元素中添加 @sartoris 这应该添加到答案中。没有它就行不通。

以上是关于Wix 为所有用户/每台机器创建非广告快捷方式的主要内容,如果未能解决你的问题,请参考以下文章

使用 WiX 创建桌面快捷方式

Wix 无法创建快捷方式

在 WIX 中运行时为快捷方式动态分配名称

Windows 设置项目中的广告快捷方式与非广告快捷方式

Wix卸载快捷方式无法正常工作

在WIX中创建使用环境变量的文件夹的快捷方式