原文: WIX 安裝部署教程(六) 為你收集的七個知識點 前段時間整理5篇WIX(Windows Installer XML)的安裝教程,但還不夠完善,這裡繼續整理了七個知識點分享給大家。WIX最新版本3.8, 點選下載下傳
- WIX安裝部署(一)同MSBuild自動生成打封包件
- WIX安裝部署(二)自定義安裝界面和行為
- WIX安裝部署(三)自定義安裝界面和行為
- WIX安裝部署(四)添加安裝檔案及快捷方式
- WIX安裝部署(五)Bootstrap 捆綁安裝
1.設定路徑變量
有的時候路徑過長,檔案又比較多,重複粘貼一個位址總是不舒服,而且要改起來也很麻煩,那這個時候就可以用統一的變量了。
項目右鍵-->屬性-->Build-->Define Preprocessor variables: 直接 vars=address; 分号隔開就可以了。

使用的時候用$(var.yourvars)就可以了
<!--自定義頁面元素-->
<WixVariable Id="WixUIDialogBmp" Value="$(var.Photoes)bk.jpg"/>
<WixVariable Id="WixUIBannerBmp" Value="$(var.Photoes)top.jpg"/>
而上圖中的Define variables是預先定義Property(在WIX中,Property就是代表變量),
其實元素Directory也是一種Property。也已經為我們定義了目錄。可以直接用。
比如講你的資料檔案安裝在C:\ProgramData檔案中(對應CommonAppDataFolder)
<Directory Id="CommonAppDataFolder">
<Directory Id="MyDATA" Name="DATA">
<Directory Id="DemoProject" Name="DemoProject" />
</Directory>
</Directory>
而Culture to build是用于生成不同語言的安裝包不同語言分号隔開。
生成對應版本。
2.注冊COM元件
這個問題困擾我好久,一開始用Action觸發bat檔案注冊,但有個cmd框,有網友提議用QtExecCmdLine靜默注冊,但沒有實作。自己寫系統資料庫一個是工作量蠻大,二個是寫不對(regedit中一大堆)。最後網友提示File标簽支援自己注冊。我就呵呵~
<DirectoryRef Id="IORegedit">
<Component Id="ForIOSERVER" Guid="{B5F03CF3-BBAE-4C03-BA06-4FE211FF41FD}">
<File Id="CxDrvOPC.dll" Source="$(var.Runtime)IORegedit\CxDrvOPC.dll" SelfRegCost="1" />
<File Id="CxDrvModbus.dll" Source="$(var.Runtime)IORegedit\CxDrvModbus.dll" SelfRegCost="1" />
</Component>
</DirectoryRef>
SelfRegCost>0就可以自動注冊,但文檔裡面描述的又比較晦澀,注冊這個檔案所需的Bytes?
3.開機自啟動
安裝之後,希望程式開機啟動。同C#程式一樣,需要将程式注冊到SOFTWARE\Microsoft\Windows\CurrentVersion\Run 目錄下即可。
<Component Id="Register">
<RegistryKey Action="create" Id="AutoStarKey" Root="HKLM" Key="SOFTWARE\Microsoft\Windows\CurrentVersion\Run">
<RegistryValue Id="autoStarKeyValue" Name="!(loc.AppName)" KeyPath="yes" Type="string" Value="[INSTALLFOLDER]HMIRun.exe" />
</RegistryKey>
</Component>
如果是C#程式
private void AutoRun()
{
//擷取程式執行路徑..
string starupPath = Application.ExecutablePath;
//表示Window系統資料庫中項級節點,讀取 Windows 系統資料庫基項HKEY_LOCAL_MACHINE
RegistryKey loca = Registry.LocalMachine;
RegistryKey run = loca.CreateSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Run");
if (run != null) run.SetValue("YourApp", starupPath);//加入注冊,參數一為注冊節點名稱(随意)
}
這裡要說明的是Root="HKLM"
Type=“String”
4.删除日志檔案
打包程式不處理的話,程式解除安裝之後可能會留下日志檔案和一些資料檔案,預設隻會解除安裝安裝時的那些檔案,新增的檔案不會删除。
這時要用RemoveFile和RemoveFolder兩個元素
<DirectoryRef Id="History" >
<Component Id="ForHistory" Guid="5628C681-0345-4BFC-2345-4C4D446401CE" KeyPath="yes">
<File Source="$(var.DemoProject)History\HistoryDB201402.sdf" />
<File Source="$(var.DemoProject)History\HistoryDB201403.sdf"/>
<File Source="$(var.DemoProject)History\HistoryDB201404.sdf"/>
<RemoveFile Id="removeDb" Name="*.sdf" On="uninstall" Directory="History"/>
<RemoveFolder Id= "Rdb1" Directory="History" On= "uninstall"/>
</Component>
</DirectoryRef>
要注意的是,如果History目錄上面還有父目錄,也需要加入RemoveFolder将父目錄清除。
5.用Orca.exe 檢視安裝包
生成的MSI檔案,其實就是一個資料庫。不同的元素就是不同的表格,我們可以借助Orca.exe來檢視,可以用來糾錯和直接修改。
我們看到Property表,可以看到已經有很多自帶的Property,而且資料是可以編輯的。 有的時候就可以直接修改不必再去生成。
6.版本更新
WIX定義了三個級别的更新,以版本資訊和産品GUID号是否改變來判斷。
<Product Id="{092B357C-6028-42CF-BCE0-44B717628935}" Name="!(loc.ProjectName)" Language="1033" Version="1.1.1.0" Manufacturer="yourCompany" UpgradeCode="{BA90B701-DB4C-4FF2-9717-88EBA32060D7}">
....
</Product>
産品ID改變表示這個版本這次是改動很大,Version的前兩位可能都改變了(Windows隻檢查前三位),而UpgradeCode不能變,變了那真就是表示是另外一個産品了。UpgradeCode 在判斷版本的時候的有用。比如直接更新版本和防止版本降級。Upgrade的Id就是上面的UpgradeCode
<!--新舊版本檢查-->
<Upgrade Id="{BA90B701-DB4C-4FF2-9717-88EBA32060D7}">
<UpgradeVersion Property="OLD_VERSION_FOUND" OnlyDetect="no" IgnoreRemoveFailure="yes" MigrateFeatures="yes" Language="1033"
Minimum="1.0.0.0" Maximum="2.0.0.0" IncludeMinimum="yes" IncludeMaximum="no" />
<UpgradeVersion Property="NEWER_VERSION_FOUND" Minimum="2.0.0.0" IncludeMinimum="no" OnlyDetect="yes" Language="1033" />
</Upgrade>
其實比較麻煩的是Minor Upgrade 和 Small Upgrade。他們的做法一樣,相當于給我們的程式打更新檔。需要4步
1.在你的WIX工程中先建立一個Patch.WXS檔案。Media的Cabinet表示後面要用到的CBA檔案的名稱,Id越大越好,要高于你MSI檔案中要更新的Media的Id,PatchBaseLine的Id會作為後面的一個引用(遺憾的是,我還沒有找到為什麼...) 而PatchFamily就比較直白了,更新的版本,對應的ProductCode(Product的Id),裡面ComponentRef 表示那些元件發生了變化。其他就不用說明了
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Patch AllowRemoval="yes" Classification="update" Comments="Patch for Your Software v. 1.1.0.0"
Description="Updates Software to v. 1.1.0.0" DisplayName="Your Software Patch 2014-05-22"
Manufacturer="YourCompany" MoreInfoURL="http://www.xxx.com/" TargetProductName="YourProduct">
<Media Id="1000" Cabinet="MyPatch.cab">
<PatchBaseline Id="MyPatch" />
</Media>
<PatchFamily Id="MyPatch" Version="1.1.1.0" ProductCode="{092B357C-6028-42CF-BCE0-44B717628935}" Supersede="yes">
<ComponentRef Id="ForHMIRT"/>
</PatchFamily>
</Patch>
</Wix>
不要包括在你的項目,右鍵從項目中解除。
2.用candle.exe 生成wixobj 檔案。
最好先把Wix目錄,添加到你的環境變量。我的電腦右鍵--屬性--進階系統設定--環境變量:編輯Path 分号隔開,加上%Wix%
然後就可以直接調用candle.exe
再用light.exe 生成wixmsp
3.再把你更新版本的pdb檔案和目前工程的pdb檔案複制到Patch.wxs同一個目錄。 調用指令生成wixmst檔案,做這些主要是要比較兩個版本的差異。當然前提是你現在的工程已經新增了元件或者元件裡面已經新增了檔案,并生成了一次。
torch.exe -p -xi older.wixpdb newpdb.wixpdb -out Patch.wixmst
4.最後生成一個MSP檔案
同上,調用Pyro.exe.
pyro.exe Patch.wixmsp -t MyPatch Patch.wixmst -out Patch.msp
生成的MSP檔案很小,但安裝效果和MSI檔案一樣。和你更新元件的多少有關系。整個過程有點繁雜,而且不清晰。最簡單的辦法還是改變版本号和ProductCode 重新釋出一個版本。上面用到了很多exe,這些都是wix自帶的工具。各自有不同的功能
7.用Heat.exe自動生成wxs檔案
我們要打包一個工程,但檔案項目非常多,要是一個一個敲xml标簽确實有點苦逼,其實WIX已經提供了heat.exe這個神奇來解決這個問題了。在D盤建立一個Runtime檔案,随便拖一些檔案進去。打開Cmd調用指令
View Code
dir表示目錄,-out 表示輸出 瞬間就生成了HeatFile.Wxs. 但一看,不是我們想要的,GuiD沒有生成,Component的Id也不直覺。 不急有更強大的指令
再看WXS檔案,指令中的dr表示建立目錄,cg 是建立ComponentGroup -var是建立變量,-gg表示自動生成GUID -gl表示GUID不帶括号,其他指令可以通過heat.exe -?來檢視
<?xml version="1.0" encoding="utf-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Fragment>
<DirectoryRef Id="RunTime">
<Directory Id="dirD818D8F32371FA9E971748891D2F242F" Name="zh-CHS" />
</DirectoryRef>
</Fragment>
<Fragment>
<ComponentGroup Id="MyFileGroup">
<Component Id="cmpFA55E9F45A78DE86628F8BCAF841C59C" Directory="RunTime" Guid="{14872EC8-B1A0-4DC9-84D5-E9F809D82230}">
<File Id="filA7DF3B9FB3655FA11EA18E662641CEBA" KeyPath="yes" Source="$(var.Dir)\HMIRun.exe.config" />
</Component>
<Component Id="cmp3F203958186210FBCF0D3406F15BEA8A" Directory="RunTime" Guid="{0249740B-AF5F-498B-9F5E-E5780DA84412}">
<File Id="fil55A2858BF646C17534199602D317C722" KeyPath="yes" Source="$(var.Dir)\NLog.config" />
</Component>
<Component Id="cmp6E035C559882EEC7EF1A85BECD96EC39" Directory="RunTime" Guid="{E2F60E84-02AB-41ED-A3BF-88C3CEB34DAD}">
<File Id="fil407F115AC10BEC92A22BDC17267AEC7B" KeyPath="yes" Source="$(var.Dir)\TemplateProject.template" />
</Component>
<Component Id="cmp077331F5CBD00FD180CA24C8FFF612A0" Directory="dirD818D8F32371FA9E971748891D2F242F" Guid="{581B54CC-0E55-4374-9CC8-F5D8784A23B6}">
<File Id="filD5FE549C3B37047CA548D43FDBBFD3A0" KeyPath="yes" Source="$(var.Dir)\zh-CHS\System.Data.SqlServerCe.Entity.resources.dll" />
</Component>
<Component Id="cmp857576E8B47F065DAA1F65C9021B5B23" Directory="dirD818D8F32371FA9E971748891D2F242F" Guid="{50B28B73-4648-4582-BF13-D517224C3617}">
<File Id="filB140B4B368F3FC0584CDDCA845EDC878" KeyPath="yes" Source="$(var.Dir)\zh-CHS\System.Data.SqlServerCe.resources.dll" />
</Component>
</ComponentGroup>
</Fragment>
</Wix>
這樣生成的檔案就很漂亮了,可以複制你的工程中去。
今天先到這裡,希望對你有幫助~
tks!:)