我正在使用 WiX 3.6。
我正在使用 WIX_Advanced 用户界面,我想用我自己的版本(称为 InstallScopeDlgDsktp)替换 InstallScopeDlg,其中包括一个用于添加桌面快捷方式的复选框。
当我这样做时,我会在 WixUI_Advanced.wxs 文件中获取对旧 InstallScopeDlg 的所有引用,并在我的主文件中覆盖它们以引用我的自定义 InstallScopeDlgDsktp 模块。
但是,当我尝试编译时,我收到一个错误,这似乎表明 RadioButton 表存在冲突,这意味着我的 InstallScopeDlgDsktp 和原始 InstallScopeDlg 都必须基于相同的属性 (WixAppFolder) 添加 RadioButton。
light Cryptobot.wixobj InstallScopeDlgDsktp.wixobj -ext WixUIExtension -out Cryptobot.msi
Microsoft (R) Windows Installer Xml Linker version 3.6.2221.0
<snip>wixlib\InstallScopeDlg.wxs(24): error LGHT0130 :
The primary key 'WixAppFolder/1' is duplicated in table 'RadioButton'. Please remove one of the entries or rename a part of the primary key to avoid the collision.
我似乎无法解决这个问题。我的问题是,当我不再引用它时,为什么它甚至会链接到原始的 InstallScopeDlg 模块中?如何阻止原始 InstallScopeDlg 添加 RadioButton?
提供的代码供参考:主 WXS 文件(UI 内容位于底部 - 可以看到我用 InstallScopeDlgDsktp 替换了所有 InstallScopeDlg 实例):
<?xml version="1.0" encoding="windows-1252"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<!-- Defines -->
<?define ProductName="Cryptobot" ?>
<?define ProductVersion="1.1.1" ?>
<Product Name="$(var.ProductName) $(var.ProductVersion)" Id="*"
UpgradeCode="MY-UPGRADE-GUID"
Language="1033" Codepage="1252" Version="$(var.ProductVersion)" Manufacturer="Crafted From Code">
<!-- The Package GUID must be changed EVERY timeyou build a new .msi. The asterisk makes this happen automatically. -->
<Package Id="*" Keywords="Installer"
Description="$(var.ProductName) $(var.ProductVersion) Setup"
Manufacturer="Crafted From Code"
InstallerVersion="200" Languages="1033" Compressed="yes" />
<Media Id="1" Cabinet="$(var.ProductName).cab" EmbedCab="yes" />
<!-- Components to install -->
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFilesFolder">
<Directory Id="CraftedFromCode" Name="Crafted From Code">
<Directory Id="APPLICATIONFOLDER" Name="$(var.ProductName)">
<Component Id="MainExecutable" Guid="MY-GUID">
<File Id="CryptobotEXE" Name="Cryptobot.exe" Source="..\Cryptobot\bin\Release\Cryptobot.exe" KeyPath="yes">
<Shortcut Id="CryptobotProgramMenuShortcut" Directory="ProgramMenuDir"
Name="$(var.ProductName)" Icon="Cryptobot.ico" IconIndex="0" Advertise="yes" />
<Shortcut Id="CryptobotDesktopShortcut" Directory="DesktopFolder"
Name="$(var.ProductName)" Icon="Cryptobot.ico" IconIndex="0" Advertise="yes" />
</File>
<RemoveFolder Id="APPLICATIONFOLDER" On="uninstall" />
</Component>
</Directory>
</Directory>
</Directory>
<!-- Start Menu Shortcut(s) -->
<Directory Id="ProgramMenuFolder" Name="Programs">
<Directory Id="ProgramMenuDir" Name="$(var.ProductName)">
<Component Id="ProgramMenuShortcut" Guid="MY-GUID" >
<RegistryValue Root="HKCU" Key="Software\Crafted From Code\Cryptobot" Name="installed" Type="integer" Value="1" KeyPath="yes" />
<RemoveFolder Id="ProgramMenuDir" On="uninstall" />
</Component>
</Directory>
</Directory>
<!-- Desktop Shortcut -->
<Directory Id="DesktopFolder">
<Component Id="DesktopShortcut" Guid="MY-GUID">
<Condition>INSTALLDESKTOPSHORTCUT</Condition>
<RegistryValue Root="HKCU" Key="Software\Crafted From Code\Cryptobot" Name="installed" Type="integer" Value="1" KeyPath="yes" />
</Component>
</Directory>
</Directory> <!-- End of TARGETDIR root directory -->
<Icon Id="Cryptobot.ico" SourceFile="Cryptobot.ico" />
<Feature Id="Complete" Level="1" Title="$(var.ProductName)"
Description="The complete package." Display="expand"
ConfigurableDirectory="APPLICATIONFOLDER">
<ComponentRef Id="MainExecutable" />
<ComponentRef Id="ProgramMenuShortcut" />
<ComponentRef Id="DesktopShortcut" />
</Feature>
<!-- Upgrade rules: If a newer version is found, don't allow installation of an older version (downgrading).
Otherwise, if an older version is already installed, remove it before installing the current version -->
<Upgrade Id="MY-UPGRADE-GUID">
<UpgradeVersion OnlyDetect="yes" Property="NEWERPRODUCTFOUND" Minimum="$(var.ProductVersion)" IncludeMinimum="no" />
<!-- Setting IncludeMaximum to yes generates a linker warning, but it means that we can install over the
same version without necessarily having to change the version number. -->
<UpgradeVersion OnlyDetect="no" Property="PREVIOUSVERSIONINSTALLED" Minimum="1.0.0" IncludeMinimum="yes" Maximum="$(var.ProductVersion)" IncludeMaximum="yes" />
</Upgrade>
<CustomAction Id='PreventDowngrading' Error='A newer version of $(var.ProductName) is already installed.' />
<InstallExecuteSequence>
<Custom Action='PreventDowngrading' After='FindRelatedProducts'>NEWERPRODUCTFOUND</Custom>
<RemoveExistingProducts After="InstallFinalize" />
</InstallExecuteSequence>
<InstallUISequence>
<Custom Action='PreventDowngrading' After='FindRelatedProducts'>NEWERPRODUCTFOUND</Custom>
</InstallUISequence>
<!-- User Interface: Use the Advanced WiX interface, which will allow 1-click installation or
per user/per machine installation & install directory to be specified -->
<UIRef Id="WixUI_Advanced" />
<UIRef Id="WixUI_ErrorProgressText" />
<Property Id="ApplicationFolderName" Value="Crafted From Code\Cryptobot" />
<Property Id="WixAppFolder" Value="WixPerUserFolder" /> <!-- Defaults to install for all users -->
<Property Id="INSTALLDESKTOPSHORTCUT" Value="1" /> <!-- Support for a desktop shortcut -->
<!-- Add a checkbox to launch the application when the installer exits -->
<Property Id="WIXUI_EXITDIALOGOPTIONALCHECKBOXTEXT" Value="Launch $(var.ProductName) when setup exits." />
<!-- Have it ticked by default -->
<Property Id="WIXUI_EXITDIALOGOPTIONALCHECKBOX" Value="1" />
<CustomAction Id="StartAppOnExit" FileKey="CryptobotEXE" ExeCommand="" Execute="immediate" Impersonate="yes" Return="asyncNoWait" />
<UI Id="WixUI_AdvancedCrypto">
<UIRef Id="WixUI_Advanced" />
<DialogRef Id="InstallScopeDlgDsktp" />
<Publish Dialog="AdvancedWelcomeEulaDlg" Control="Advanced" Event="NewDialog" Value="InstallScopeDlgDsktp" Order="1">!(wix.WixUISupportPerMachine) AND !(wix.WixUISupportPerUser)</Publish>
<Publish Dialog="InstallScopeDlgDsktp" Control="Back" Event="NewDialog" Value="AdvancedWelcomeEulaDlg">1</Publish>
<!-- override default WixAppFolder of WixPerMachineFolder as standard user won't be shown the radio group to set WixAppFolder -->
<Publish Dialog="InstallScopeDlgDsktp" Control="Next" Property="WixAppFolder" Value="WixPerUserFolder" Order="1">!(wix.WixUISupportPerUser) AND NOT Privileged</Publish>
<Publish Dialog="InstallScopeDlgDsktp" Control="Next" Property="ALLUSERS" Value="{}" Order="2">WixAppFolder = "WixPerUserFolder"</Publish>
<Publish Dialog="InstallScopeDlgDsktp" Control="Next" Property="ALLUSERS" Value="1" Order="3">WixAppFolder = "WixPerMachineFolder"</Publish>
<Publish Dialog="InstallScopeDlgDsktp" Control="Next" Property="APPLICATIONFOLDER" Value="[WixPerUserFolder]" Order="4">WixAppFolder = "WixPerUserFolder"</Publish>
<Publish Dialog="InstallScopeDlgDsktp" Control="Next" Property="APPLICATIONFOLDER" Value="[WixPerMachineFolder]" Order="5">WixAppFolder = "WixPerMachineFolder"</Publish>
<Publish Dialog="InstallScopeDlgDsktp" Control="Next" Event="NewDialog" Value="FeaturesDlg" Order="6">WixAppFolder = "WixPerUserFolder"</Publish>
<Publish Dialog="InstallScopeDlgDsktp" Control="Next" Event="NewDialog" Value="InstallDirDlg" Order="7">WixAppFolder = "WixPerMachineFolder"</Publish>
<Publish Dialog="FeaturesDlg" Control="Back" Event="NewDialog" Value="InstallScopeDlgDsktp">NOT Installed AND WixAppFolder = "WixPerUserFolder"</Publish>
<Publish Dialog="InstallDirDlg" Control="Back" Event="NewDialog" Value="InstallScopeDlgDsktp">!(wix.WixUISupportPerUser)</Publish>
<!-- Add the check box for launching the app on completion -->
<Publish Dialog="ExitDialog" Control="Finish" Order="1" Event="DoAction" Value="StartAppOnExit">WIXUI_EXITDIALOGOPTIONALCHECKBOX = 1 AND NOT Installed</Publish>
</UI>
</Product>
</Wix>
InstallScopeDlgDsktp 文件只是 InstallScopeDlg 的副本,添加了一个复选框并且名称已更改:
<snip>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Fragment>
<UI>
<Dialog Id="InstallScopeDlgDsktp" Width="370" Height="270" Title="!(loc.InstallScopeDlg_Title)" KeepModeless="yes">
<Control Id="BannerBitmap" Type="Bitmap" X="0" Y="0" Width="370" Height="44" TabSkip="no" Text="!(loc.InstallScopeDlgBannerBitmap)" />
<Control Id="BannerLine" Type="Line" X="0" Y="44" Width="370" Height="0" />
<Control Id="BottomLine" Type="Line" X="0" Y="234" Width="370" Height="0" />
<Control Id="Description" Type="Text" X="25" Y="23" Width="280" Height="20" Transparent="yes" NoPrefix="yes" Text="!(loc.InstallScopeDlgDescription)" />
<Control Id="Title" Type="Text" X="15" Y="6" Width="200" Height="15" Transparent="yes" NoPrefix="yes" Text="!(loc.InstallScopeDlgTitle)" />
<Control Id="BothScopes" Type="RadioButtonGroup" X="20" Y="55" Width="330" Height="120" Property="WixAppFolder" Hidden="yes">
<RadioButtonGroup Property="WixAppFolder">
<RadioButton Value="WixPerUserFolder" X="0" Y="0" Width="295" Height="16" Text="!(loc.InstallScopeDlgPerUser)" />
<RadioButton Value="WixPerMachineFolder" X="0" Y="60" Width="295" Height="16" Text="!(loc.InstallScopeDlgPerMachine)" />
</RadioButtonGroup>
<Condition Action="show">Privileged AND (!(wix.WixUISupportPerUser) AND !(wix.WixUISupportPerMachine))</Condition>
</Control>
<Control Id="PerUserDescription" Type="Text" X="33" Y="70" Width="300" Height="36" Hidden="yes" NoPrefix="yes" Text="!(loc.InstallScopeDlgPerUserDescription)">
<Condition Action="show">!(wix.WixUISupportPerUser)</Condition>
</Control>
<Control Id="NoPerUserDescription" Type="Text" X="33" Y="70" Width="300" Height="36" Hidden="yes" NoPrefix="yes" Text="!(loc.InstallScopeDlgNoPerUserDescription)">
<Condition Action="show">NOT !(wix.WixUISupportPerUser)</Condition>
</Control>
<Control Id="PerMachineDescription" Type="Text" X="33" Y="131" Width="300" Height="36" Hidden="yes" NoPrefix="yes" Text="!(loc.InstallScopeDlgPerMachineDescription)">
<Condition Action="show">Privileged</Condition>
</Control>
<Control Id="DesktopShortcutCheckBox" Type="CheckBox" X="20" Y="160" Width="290" Height="17" Property="INSTALLDESKTOPSHORTCUT" CheckBoxValue="1" Text="Create a shortcut on the desktop." />
<Control Id="Back" Type="PushButton" X="180" Y="243" Width="56" Height="17" Text="!(loc.WixUIBack)" />
<Control Id="Next" Type="PushButton" X="236" Y="243" Width="56" Height="17" Default="yes" Text="!(loc.WixUINext)" />
<Control Id="Cancel" Type="PushButton" X="304" Y="243" Width="56" Height="17" Cancel="yes" Text="!(loc.WixUICancel)">
<Publish Event="SpawnDialog" Value="CancelDlg">1</Publish>
</Control>
</Dialog>
</UI>
</Fragment>
</Wix>