在 WiX Bundle 中包含 .NET 安装程序未检测是否已安装 [英] Including .NET installer in WiX Bundle not detecting if already installed
问题描述
我使用的是 WiX 3.7,我无法让简单的 <PackageGroupRef Id="NetFx40Web"/> 包元素工作,因为它没有带来 Net FX 安装程序包,也没有将其嵌入安装程序.exe.我已经在我的 Bundle.wxs
文件中为此创建了我自己的包,但我仍然遇到问题.似乎总是尝试安装 .NET 4,即使机器已经安装了 .NET.
我不太确定 InstallCondition 和 DetectCondition 之间的区别.我认为InstallCondition 用于安装包,如果评估为真,否则卸载它.这如何处理通常permanent=yes 的事情,例如大多数先决条件?DetectCondition 几乎相反,我认为,因为它检查它是否已经在系统上,如果是,则不安装它.
以下是我在 Visual Studio WiX Bootstrapper 项目中的完整 Bundle.wxs
文件.我正在尝试查看 .NET 4.0 注册表项之外的注册表和范围.如果它存在,那么我不想安装 .NET 4.如果它不存在,则安装它.但是,这不起作用,它总是尝试安装 .NET.
<BootstrapperApplicationRef Id="WixStandardBootstrapperApplication.RtfLicense"/><链><PackageGroupRef Id="Netfx4Full"/><MsiPackageId="MyProgramInstaller"SourceFile="$(var.MyProgramInstaller.TargetPath)"压缩=否"/></链></捆绑包><片段><属性 ID="NET40_FULL_INSTALL_32"><注册表搜索Id ="SearchNet40_32bit"根=HKLM"Key="SOFTWARE\Microsoft\Net Framework Setup\NDP\v4\Full"名称=版本"输入 =原始"/></属性><财产Id="NET40_FULL_INSTALL_64"><注册表搜索Id ="SearchNet40_64bit"根=HKLM"Key="SOFTWARE\Microsoft\Net Framework Setup\NDP\v4\Full"名称=版本"输入=原始"Win64="是"/></属性><WixVariableId="WixMbaPrereqPackageId"值="Netfx4Full"/><WixVariableId="WixMbaPrereqLicenseUrl"值="NetfxLicense.rtf"/><包组Id="Netfx4Full"><执行包Id="Netfx4Full"缓存=否"压缩=否"PerMachine="是"永久=是"重要=是"SourceFile="C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bootstrapper\Packages\DotNetFX40\dotNetFx40_Full_x86_x64.exe"DetectCondition="NET40_FULL_INSTALL_32 或 NET40_FULL_INSTALL_64"DownloadUrl="http://go.microsoft.com/fwlink/?LinkId=164193"/></PackageGroup></片段></Wix>
引导程序安装程序日志:
[010C:2FB0][2013-05-10T12:07:07]w120:检测到部分缓存的包:Netfx4Full,无效负载:Netfx4Full,原因:0x80070570[010C:2FB0][2013-05-10T12:07:07]i052:条件NETFRAMEWORK40"评估为假.[010C:2FB0][2013-05-10T12:07:07]w120:检测到部分缓存的包:MyInstaller,无效负载:f4832BA0972BDE9B6FA8A19FBB614A7BA,原因:0x80070570[010C:2FB0][2013-05-10T12:07:07]i101:检测到包:Netfx4Full,状态:不存在,缓存:部分
更新,提供解决方案.我使用内置的 WiX RegistrySearch 来确定它是否已安装.我必须在我的 Bundle 项目中引用 WixUtilExtension.dll.这是更新后的 Bundle.wxs:
<BootstrapperApplicationRef Id="WixStandardBootstrapperApplication.RtfLicense"/><链><PackageGroupRef Id="Netfx4Full"/><!-- TODO:定义链接的包列表.--><!-- <MsiPackage SourceFile="path\to\your.msi"/>--><MsiPackageId="MyProgramInstaller"SourceFile="$(var.MyProgramInstaller.TargetPath)"压缩=否"/></链></捆绑包><片段><util:RegistrySearchRef Id="NETFRAMEWORK40"/><包组Id="Netfx4Full"><执行包Id="Netfx4FullExe"缓存=否"压缩=否"PerMachine="是"永久=是"重要=是"SourceFile="C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bootstrapper\Packages\DotNetFX40\dotNetFx40_Full_x86_x64.exe"InstallCommand="/q/norestart/ChainingPackage FullX64Bootstrapper"DetectCondition="NETFRAMEWORK40"DownloadUrl="http://go.microsoft.com/fwlink/?LinkId=164193"/></PackageGroup></片段></Wix>
这里似乎有很多问题.
听起来根本问题是如何将 NETFX 安装嵌入到您的包中.如果是这样,那么 WixNetfxExtension
今天不支持它是正确的.您必须定义自己的副本,并且您的副本已关闭(可能从 src\ext\NetFxExtension\wixlib
中的内容复制).要将 NETFX 嵌入到您的包中,您唯一需要更改的是将 ExePackage/@Compressed
属性设置为 'yes'
.或者您可以关闭 Compressed
属性,它会跟随您的 Bundle
元素(默认为 'yes'
)的压缩.>
其次,DetectCondition
确实确定包是否在机器上.Burn 会根据包是否在机器上来做符合逻辑的事情.例如,在安装期间,如果软件包不存在,Burn 将安装该软件包,但如果该软件包已存在,则不会执行任何操作.当然,不存在的和永久的软件包会忽略卸载请求.
第三,InstallCondition
指示是否应该在机器上安装包.如果它评估为真,则可以安装该软件包(如果不存在并要求安装).如果计算结果为 false,则移除包(如果存在).
注意:您的注册表搜索和条件与 WiX 工具集中用于检测 NETFX 的内容略有不同.以下是 WiX 工具集使用的 NETFX 检测:
<块引用>
DetectCondition
就是 "NETFRAMEWORK40"
.这种差异可能可以解释您所看到的问题.
I'm on WiX 3.7, and I can't get the simple <PackageGroupRef Id="NetFx40Web"/> bundle element to work, as it doesn't bring across the Net FX installer package, or embed it in the setup.exe. I've resorted to creating my own package for this in my Bundle.wxs
file, but I am still having trouble. It seems to always try to install .NET 4, even if the machine already has .NET installed.
I'm not quite sure of the difference between InstallCondition and DetectCondition. I think InstallCondition is used to install the package if the evaluation is true, otherwise uninstall it. How does this work with things that are typically permanent=yes, such as most pre-requisites? DetectCondition is almost the opposite, I think, in that it checks if it's already on the system, and if so, doesn't install it.
Below is my full Bundle.wxs
file which is in a Visual Studio WiX Bootstrapper project. I'm attempting to look at the registry and scope out of .NET 4.0 registry key is there. If it is present, then I don't want to install .NET 4., and if it's not there, then install it. But, this isn't working, and it always attempts to install .NET.
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Bundle
Name="MyProgramBootstrapper"
Version="1.0.0.0"
Manufacturer="Microsoft"
UpgradeCode="{2299B51D-9FD8-4278-90C8-2B79DB37F402}">
<BootstrapperApplicationRef Id="WixStandardBootstrapperApplication.RtfLicense" />
<Chain>
<PackageGroupRef Id="Netfx4Full"/>
<MsiPackage
Id="MyProgramInstaller"
SourceFile="$(var.MyProgramInstaller.TargetPath)"
Compressed="no"/>
</Chain>
</Bundle>
<Fragment>
<Property Id="NET40_FULL_INSTALL_32">
<RegistrySearch
Id ="SearchNet40_32bit"
Root="HKLM"
Key="SOFTWARE\Microsoft\Net Framework Setup\NDP\v4\Full"
Name="Version"
Type ="raw"/>
</Property>
<Property
Id="NET40_FULL_INSTALL_64">
<RegistrySearch
Id ="SearchNet40_64bit"
Root="HKLM"
Key="SOFTWARE\Microsoft\Net Framework Setup\NDP\v4\Full"
Name="Version"
Type ="raw"
Win64="yes" />
</Property>
<WixVariable
Id="WixMbaPrereqPackageId"
Value="Netfx4Full" />
<WixVariable
Id="WixMbaPrereqLicenseUrl"
Value="NetfxLicense.rtf" />
<PackageGroup
Id="Netfx4Full">
<ExePackage
Id="Netfx4Full"
Cache="no"
Compressed="no"
PerMachine="yes"
Permanent="yes"
Vital="yes"
SourceFile="C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bootstrapper\Packages\DotNetFX40\dotNetFx40_Full_x86_x64.exe"
DetectCondition="NET40_FULL_INSTALL_32 OR NET40_FULL_INSTALL_64"
DownloadUrl="http://go.microsoft.com/fwlink/?LinkId=164193"/>
</PackageGroup>
</Fragment>
</Wix>
Bootstrapper installer log:
[010C:2FB0][2013-05-10T12:07:07]w120: Detected partially cached package: Netfx4Full, invalid payload: Netfx4Full, reason: 0x80070570
[010C:2FB0][2013-05-10T12:07:07]i052: Condition 'NETFRAMEWORK40' evaluates to false.
[010C:2FB0][2013-05-10T12:07:07]w120: Detected partially cached package: MyInstaller, invalid payload: f4832BA0972BDE9B6FA8A19FBB614A7BA, reason: 0x80070570
[010C:2FB0][2013-05-10T12:07:07]i101: Detected package: Netfx4Full, state: Absent, cached: Partial
Update, with solution. I used the built-in WiX RegistrySearch to determine if it's installed. I had to reference the WixUtilExtension.dll in my Bundle project. Here's the updated Bundle.wxs:
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi"
xmlns:netfx="http://schemas.microsoft.com/wix/NetFxExtension"
xmlns:util="http://schemas.microsoft.com/wix/UtilExtension"
>
<Bundle
Name="MyProgramBootstrapper"
Version="1.0.0.0"
Manufacturer="Microsoft"
UpgradeCode="{2299B51D-9FD8-4278-90C8-2B79DB37F402}">
<BootstrapperApplicationRef Id="WixStandardBootstrapperApplication.RtfLicense" />
<Chain>
<PackageGroupRef Id="Netfx4Full"/>
<!-- TODO: Define the list of chained packages. -->
<!-- <MsiPackage SourceFile="path\to\your.msi" /> -->
<MsiPackage
Id="MyProgramInstaller"
SourceFile="$(var.MyProgramInstaller.TargetPath)"
Compressed="no" />
</Chain>
</Bundle>
<Fragment>
<util:RegistrySearchRef Id="NETFRAMEWORK40"/>
<PackageGroup
Id="Netfx4Full">
<ExePackage
Id="Netfx4FullExe"
Cache="no"
Compressed="no"
PerMachine="yes"
Permanent="yes"
Vital="yes"
SourceFile="C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bootstrapper\Packages\DotNetFX40\dotNetFx40_Full_x86_x64.exe"
InstallCommand="/q /norestart /ChainingPackage FullX64Bootstrapper"
DetectCondition="NETFRAMEWORK40"
DownloadUrl="http://go.microsoft.com/fwlink/?LinkId=164193"/>
</PackageGroup>
</Fragment>
</Wix>
There seem to be a lot of questions here.
It sounds like the root question is how to include the NETFX install embedded in your bundle. If so, you are correct that the WixNetfxExtension
doesn't support that today. You do have to define your own copy and your copy is close (maybe copied from what is in the src\ext\NetFxExtension\wixlib
). The only thing you need to change to get the NETFX embedded in your bundle is to set the ExePackage/@Compressed
attribute to 'yes'
. Or you could leave the Compressed
attribute off and it will follow the compression of your Bundle
element (which defaults to 'yes'
).
Second, the DetectCondition
does determine if the package is on the machine. Burn will do the logical things based on whether the package is on the machine. For example, during install Burn will install the package if the package is absent but will do nothing if the package is already present. Of course, absent and permanent packages ignore requests to uninstall.
Third, the InstallCondition
indicates whether the package should ever be installed on the machine. If it evaluates to true then the package can be installed (if absent and requested to be installed). If it evaluates to false the package is removed (if present).
Note: your registry search and conditions are a little different from what is used in the WiX toolset to detect NETFX. The following is the detection for NETFX the WiX toolset uses:
<util:RegistrySearch
Id="NETFRAMEWORK40"
Variable="NETFRAMEWORK40"
Root="HKLM"
Key="SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full"
Value="Install"
Result="value" />
The
DetectCondition
is then just"NETFRAMEWORK40"
. That difference might explain the issues you are seeing.
这篇关于在 WiX Bundle 中包含 .NET 安装程序未检测是否已安装的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!