WiX Bundle bal: condition - util: переменная RegistrySearch всегда false
Я хочу, чтобы моя установка завершилась с ошибкой, если сторонний программный элемент не установлен. Я добавил Fragment
с util:RegistrySearch
и a bal:Condition
в Bundle
, но я не могу заставить его работать. ThirdPartyCOMLibraryInstalled
никогда не оценивает значение true. Я подтвердил, что ключ существует, и значение, которое я использую для Key
, является правильным - я копирую/вставляю имя из выбранного ключа в regedit. В журнале нет ошибок.
Я создаю установщик с помощью WiXTools 3.7 в Visual Studio 2012 на Windows 7 64-бит и тестирую как на Windows XP, так и на Windows XP и 7 64-разрядных.
Поиск в Интернете для других примеров для util:RegistrySearch
Я просмотрел следующие альтернативные формы для тестового выражения условия.
-
ThirdPartyCOMLibraryInstalled = 0
- всегда False
-
ThirdPartyCOMLibraryInstalled <> 1
- всегда True
Вот код Bundle
:
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi"
xmlns:util="http://schemas.microsoft.com/wix/UtilExtension"
xmlns:netfx="http://schemas.microsoft.com/wix/NetFxExtension"
xmlns:bal="http://schemas.microsoft.com/wix/BalExtension">
<Bundle Name="!(bind.packageName.MyApp)"
Version="!(bind.packageVersion.MyApp)"
Manufacturer="!(bind.packageManufacturer.MyApp)"
UpgradeCode="a07ce1d5-a7ed-4d89-a7ee-fb13a5dd69ba"
Copyright="Copyright (c) 2013 [Bundle/@Manufacturer]. All rights reserved."
IconSourceFile="$(var.My_Application1.ProjectDir)MyCo.ico">
<bal:Condition Message="ThirdParty Application COM Library Required. Please (re)install ThirdParty Application and ensure 'Windows API' and '.NET Components' are installed."
>ThirdPartyCOMLibraryInstalled</bal:Condition>
<Variable Name="InstallFolder"
Type="string"
Value="[ProgramFilesFolder]MyCo Systems\My_Application\"/>
<BootstrapperApplicationRef
Id="WixStandardBootstrapperApplication.HyperlinkLicense" >
<bal:WixStandardBootstrapperApplication
ThemeFile="Resources\HyperlinkTheme.xml"
LaunchTarget="[InstallFolder]My_Application.exe"
LocalizationFile="Resources\HyperlinkTheme.wxl"
SuppressRepair="yes"
SuppressOptionsUI="yes"
LicenseUrl=""
LogoFile="Resources/MyCoLogoWt64.png"
/>
</BootstrapperApplicationRef>
<Chain>
<PackageGroupRef Id="NetFx40Redist"/>
<MsiPackage Id ="MyApp"
Vital="yes"
Name="My Application"
SourceFile="$(var.MyApp_Install.TargetDir)MyApp_Install.msi">
<MsiProperty Name="INSTALLLOCATION"
Value="[InstallFolder]" />
</MsiPackage>
</Chain>
</Bundle>
<Fragment>
<util:RegistrySearch
Variable="ThirdPartyCOMLibraryInstalled"
Result="exists"
Root="HKLM"
Key="SOFTWARE\Classes\ThirdPartyId.Server\CLSID"/>
</Fragment>
</Wix>
Ответы
Ответ 1
Корневая проблема заключается в том, что RegistrySearch
находится в отдельном Fragment
, который никогда не ссылается. Поскольку ничто в Fragment
не ссылается, компоновщик "оптимизирует" содержимое Fragment
, и поиск не включен в ваш Bundle
.
Кроме того, можно утверждать, что тот факт, что есть ссылка на переменную, указанную в поиске в Condition
, что компоновщик должен иметь возможность выяснить, что поиск необходим. Однако это не работает во всех случаях.
К счастью, решение довольно простое! Вам даже нужно выбрать один из двух:
- Переместите элемент
RegistrySearch
в элемент Bundle
.
- Добавьте элемент
RegistrySearchRef
в элемент Bundle
, чтобы ссылаться на RegistrySearch
в Fragment
. Вам также необходимо указать атрибуты RegistrySearch
и Id
.
Лично мне нравится вариант второй, и я, вероятно, даже переместил бы Condition
в Fragment
, чтобы сгруппировать все это вместе. Что-то похожее на:
<Bundle ...>
<util:RegistrySearchRef Id='SearchForThirdParty' />
...
</Bundle>
<Fragment>
<util:RegistrySearch
Id='SearchForThirdParty'
Variable="ThirdPartyCOMLibraryInstalled"
Result="exists"
Root="HKLM"
Key="SOFTWARE\Classes\ThirdPartyId.Server\CLSID"/>
<bal:Condition Message="ThirdParty Application COM Library Required. Please (re)install ThirdParty Application and ensure 'Windows API' and '.Net Components' are installed.">ThirdPartyCOMLibraryInstalled</bal:Condition>
</Fragment>
</Wix>
Это должно сделать это.