天天看點

C# 中執行 msi 安裝實作思路主要接口介紹主要代碼

平時使用 msiexec.exe 習慣了,是以最直接的想法就是在一個子程序中執行:

這樣固然是能夠完成任務,但是不是太簡陋了? 安裝開始後我們想取消這次安裝怎麼辦? 或者我們還想要拿到一些安裝進度的資訊。

其實可以通過調用三個 windows API 輕松搞定這個事兒!下面的 C# demo 用一個自定義 Form 來訓示多個 MSI 檔案的安裝過程。Form 上放的是一個滾動條,并且配合一個不斷更新的 label。先看看 demo 長什麼樣子。

下面是安裝過程中的 UI:

點選 Cancel 按鈕取消安裝後的 UI:

我們先來了解一下主要用到的幾個 win32 API。

首先是 MsiSetInternalUI 方法:

在調用 msiexec.exe 時,我們通過指定 /q 參數讓安裝過程顯示不同的 UI。如果不顯示UI的話就要使用參數 /qn 。MsiSetInternalUI 方法就是幹這個事兒的。通過下面的調用就可以去掉 msi 中自帶的 UI:

接下來是 MsiSetExternalUI 方法:

MsiSetExternalUI 函數允許指定一個使用者定義的外部 UI handler 用來處理安裝過程中産生的消息。這個外部的 UI handler 會在内部的 UI handler 被調用前調用。 如果在外部的 UI handler 中傳回非 0 的值,就說明這個消息已經被處理。

這個外部的 UI handler 就是 MsiSetExternalUI 方法的第一個參數,我們通過實作這個 handler 來處理自己感興趣的消息, 比如當安裝進度變化後去更新進度條。或者通過它傳遞我們的消息給 msi,比如說告訴 msi,停止安裝,執行 cancel 操作。使用這個方法需要注意的是,當你完成安裝後一定要把原來的 handler 設回去。否則以後執行 msi 安裝包可能會出問題。

MSDN 上有一個 MsiInstallUIHandler 的 demo,感興趣的同學可以去看看。

下面是 MsiInstallProduct 方法:

正如其名,這個是真正幹活兒的方法。

實在忍不住要介紹第四個方法,雖然它對實作目前的功能來說是可選的,但對一個産品來說,它卻是用來救命的。

這個方法會把安裝 log 儲存到你傳遞給它的檔案路徑。有了它生活就會 happy 很多,很多… 否則當使用者告訴你安裝失敗時,你一定會抓狂的。

好了,下面是 MyInstaller demo 的主要代碼:

簡單說明一下,使用者定義的 UI 運作在主線程中,使用 BackgroundWorker 執行安裝任務。在安裝進行的過程中可以把 cancel 資訊傳遞給 MsiProgressHandler,當MsiProgressHandler 檢測到 cancel 資訊後通過傳回值告訴 msi 的執行引擎,執行 cancel 操作(msi的安裝過程是相當嚴謹的,可不能簡單的殺掉安裝程序了事!)。

這樣,一個支援 cancel 的自定義 UI 的安裝控制程式就 OK了(demo哈)。如果要安裝多個 msi 隻需在 Install 方法中循環就可以了。

本文轉自xmgdc51CTO部落格,原文連結:http://blog.51cto.com/12953214/1942277 ,如需轉載請自行聯系原作者

繼續閱讀