原文: Wix 安裝部署(五) Bootstrapper 捆綁安裝 Wix的xml配置确實很費勁,忍不住有點像吐槽一下,前四篇完成的功能在Windows Installer中通過配置能很快的弄出來。可惜有很多加了鎖的功能在InstallShield Limited Edition 版本中是用不了的。 但基本滿足安裝需求了。按照這個目錄(下圖)一個一個去配,配出來的也像樣了(這裡就不說了)。但是無法定制行為,以及打更新檔等。wix又是一個極端,完全依賴xml。這兩天想解決自動檢測.net framework版本沒有就自動安裝的功能和注冊dll的就很費勁。 在Windows Installer中分别在Redistributables和Registry中設定就行了,特别是注冊,可以直接把目錄從你自己的電腦上拖過來。但今天要講的,就是wix中的Bootstrapper 項目,制作一個捆綁安裝程式,也是Windows Installer中沒有的。将多個需要安裝的檔案,按照順序一次性裝完。
一、Bootstrapper 初識
起因:wix的Setup 項目是無法自動安裝.net framework的,必須要通過bootstrapper 應用程式去驅動wix中的Burn引擎來安裝。在wix中隻能判斷有無合适的版本再終止安裝。前提是要引入WixNetFxExtension.dll。xml代碼如下
<PropertyRef Id="NETFRAMEWORK40FULL"/>
<Condition Message="This application requires .NET Framework 4.0"> <![CDATA[Installed OR NETFRAMEWORK40FULL]]> </Condition>
是以需要建立一個bootstrapper 項目
會生成一個Bundle的wxs檔案 支援四種檔案格式
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Bundle Name="Bootstrapper1" Version="1.0.0.0" Manufacturer="" UpgradeCode="dcf1682c-0a71-460f-9179-793a502c444b">
<BootstrapperApplicationRef Id="WixStandardBootstrapperApplication.RtfLicense" />
<Chain>
<!-- TODO: Define the list of chained packages. -->
<!-- <MsiPackage SourceFile="path\to\your.msi" /> -->
</Chain>
</Bundle>
</Wix>
View Code
二、如何捆綁
目的:檢測.net版本,沒有比對的就自動安裝,然後再安裝我們自己的工程。
1.先在Bootstrapper工程中引用WixNetFxExtension.dll 這個動态連結庫中 已經包含了各種.net 版本
2.在Chain 元素中添加安裝清單。
<Chain>
<PackageGroupRef Id="NetFx40Web"/>
<MsiPackage Id="Scada" SourceFile="D:\VS2012\SCADASetup\SCADASetup\bin\Debug\SCADASetup.msi"></MsiPackage>
</Chain>
這裡PackageGroupRef Id的意思就是沒有.Net Framework4.0就從web上下載下傳了安裝,當然你如果安裝了4.5,這個是向下相容的,不會再給你裝一個4.0。其他版本的如下所示:
NetFx40Web | .Net Framework 4.0 Full web setup. |
NetFx40Redist | .Net Framework 4.0 Full standalone setup. |
NetFx40ClientWeb | .Net Framework 4.0 Client Profile web setup. |
NetFx40ClientRedist | .Net Framework 4.0 Client Profile standalone setup. |
NetFx45Web | .Net Framework 4.5 web setup. |
NetFx45Redist | .Net Framework 4.5 standalone setup. |
這裡的MsiPackage就是我們自己的打包工程,會在.net版本确定之後安裝,且位址對就行了,沒有必要複制到根目錄下,生成的時候他會自動一個exe安裝檔案。 但是 是以在Bootstrapper中的安裝程式都是沒有視窗的。安裝順序一個個默默的裝完,沒有上一步,下一步。和Click Once部署的一樣。一次性裝完。
如果要讓MSI安裝檔案顯示界面,要設定屬性DisplayInternalUI為yes 就可以看展示出界面了
<PackageGroupRef Id="NetFx40Web"/>
<MsiPackage SourceFile="$(var.MSIPath)SCADASetupWix.msi" DisplayInternalUI="yes" />
3.安裝檔案設定。
上面就是一個簡單的捆綁安裝程式了,我們還可以進一步配置。 可以現在Fragment元素中把檔案先設定好,在加入到連結清單中。
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi" xmlns:bal="http://schemas.microsoft.com/wix/BalExtension"
xmlns:netfx="http://schemas.microsoft.com/wix/NetFxExtension"
xmlns:util="http://schemas.microsoft.com/wix/UtilExtension">
<Bundle Name="DIAView" Version="1.0.0.0" Manufacturer="Delta" UpgradeCode="87714fb5-9cdb-4323-af55-821c05974378" IconSourceFile="$(var.Photoes)diaapp.ico" Compressed="yes" >
<BootstrapperApplicationRef Id="WixStandardBootstrapperApplication.RtfLicense" >
<bal:WixStandardBootstrapperApplication LicenseFile="$(var.Photoes)license.rtf" LogoFile="$(var.Photoes)dialogo.jpg" />
</BootstrapperApplicationRef>
<!--<BootstrapperApplicationRef Id="ManagedBootstrapperApplicationHost"> IconSourceFile="$(var.Photoes)diaapp.ico"
<bal:WixStandardBootstrapperApplication LicenseFile="$(var.Photoes)license.rtf" LogoFile="$(var.Photoes)scon.ico" />
</BootstrapperApplicationRef>-->
<Chain>
<!--<PackageGroupRef Id="NetFx40Web" />-->
<PackageGroupRef Id="Netfx4Full" />
<MsiPackage Id="DIAView" SourceFile="$(var.Dia)DIAViewSetUp.msi" Compressed="no" DisplayInternalUI="yes"/>
</Chain>
</Bundle>
<Fragment>
<!--<PackageGroup Id="Netfx4Full">
<ExePackage Id="Netfx4Full" Cache="no" Compressed="no" PerMachine="yes" Permanent="yes" Vital="yes" InstallCommand="/q"
SourceFile="$(var.Dia)dotNetFx40_Full_x86_x64.exe"
DetectCondition="(Netfx4FullVersion="4.0.30319") AND (NOT VersionNT64 OR (Netfx4x64FullVersion="4.0.30319"))"
DownloadUrl="http://go.microsoft.com/fwlink/?LinkId=164193"
InstallCondition="(VersionNT >= v5.1 OR VersionNT64 >= v5.1) AND (NOT (Netfx4FullVersion="4.0.30319" OR Netfx4x64FullVersion="4.0.30319"))"/>
</PackageGroup>-->
<util:RegistrySearchRef Id="NETFRAMEWORK40"/>
<PackageGroup
Id="Netfx4Full">
<ExePackage
Id="Netfx4FullExe"
Cache="no"
Compressed="no"
PerMachine="yes"
Permanent="yes"
Vital="yes"
SourceFile="$(var.Dia)dotNetFx40_Full_x86_x64.exe"
InstallCommand="/q /norestart "
DetectCondition="NETFRAMEWORK40"
DownloadUrl="http://go.microsoft.com/fwlink/?LinkId=164193"/>
</PackageGroup>
</Fragment>
</Wix>
(注釋部分的檢測.net4.0有問題,每次都會裝一次.net4.0 甚至會在32位系統中造成重新開機。)
ExePackage 就是專門針對exe檔案,MsiPackage正對msi檔案,其他以此類推。說幾個重要的屬性:Compress=“yes” 表示是壓縮,no的話,debug中這個安裝包就會獨立出來,全部是yes的話最終就一個exe檔案。
Permanent="yes" 表示如果是解除安裝的話,這個檔案會保留,為no的話,使用者解除安裝的時候會一起解除安裝掉。VersionNT 變量代表系統,5.1指的是xp
4.判斷是否注冊。
我們用RegistrySearch來搜尋系統資料庫,切可以制定檢測順序
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi"
xmlns:util="http://schemas.microsoft.com/wix/UtilExtension">
<Fragment>
<util:RegistrySearch Id="Path"
Variable="UniqueId"
Root="HKLM,SOFTWARE\Microsoft\MyProduct\Unique Id\"
Key="Product"
Result="Value" />
<util:RegistrySearch
Variable="patchLevel"
Root="HKLM,SOFTWARE\Microsoft\MyProduct\[UniqueId]\Setup"
Key="PatchLevel"
Result="Exists"
After="Path" />
</Fragment>
</Wix>
這裡的表示的就是在執行Path之後在執行第二個系統資料庫搜尋,且結果你存儲在Variable中的,而這個Variable就可以作為,是否安裝的一個條件。
<ExePackage
SourceFile="[sources]\packages\shared\MyPackage.exe"
DownloadURL="http://mywebdomain.com/?mypackage.exe
InstallCommand="/q /ACTION=Install"
RepairCommand="/q ACTION=Repair /hideconsole"
UninstallCommand="/q ACTION=Uninstall /hideconsole "
InstallCondition="x86 = 1 AND OSVersion >= v5.0.5121.0 AND patchLevel = 0" />
</PackageGroup>
這種一次性安裝的方式還是覺得不太好,有些強制性。這裡隻做個簡單的參照。
很多PC軟體都是可以自動檢測版本,下載下傳更新,VS自帶的ClickOnce也可以運作前自己動檢測,發現新版本會去提示下載下傳更新,需要借助一個釋出網站就行。但那個可配置性就更 低了。應該還有其他的方法,求路過大俠指點一二。