天天看點

ClickOnce部署

(1):一些釋出方式

ClickOnce是什麼玩意兒,這個問題嘛,在21世紀的網際網路嚴重發達的時代,估計也沒有必要大費奏章去介紹了,弄不好的話,還有抄襲之嫌。是以,有關ClickOnce的介紹,各位朋友可以直接查找MSDN文檔,或者看下面這裡,這是百度百科上的,其實也是Ctrl + C版本。http://baike.baidu.com/view/1390498.htm

如果你對這些理論的東西不感興趣,沒關系,上面所提及的内容你完全可以無視之。我們隻要知道,ClickOnce是一種應用程式部署方式即可。那什麼是部署呢? 我們不妨查一查詞典,部署的釋義為安排、布置等,而放到我們的應用程式來說,我們通俗的叫法就是安裝。即把你開發好的應用程式布置到客戶的計算機上,或者說安裝到客戶的計算機上,這就是部署。

是以我們可以說ClickOnce應用程式就是一類安裝包裝,它可以一步到位進行安裝,而不像我們所使用的傳統安裝包那樣,要N個"下一步",然後才是完成。

也許有人也說,釋出ClickOnce包不是很簡單嗎? 在VS裡面點幾下滑鼠就完事了嗎? 你還拿來寫部落格幹嗎? 首先,法律并沒有規定簡單的東西不能拿來寫部落格;其次,對于許多初學者朋友來說,我想是有參考價值,至少會有;再者,有些小問題可能大家經常會忽略的。

我們先來釋出一個Windows Forms應用程式,練練手。

準備條件:先確定安裝了IIS,如果沒有,就趕緊動手吧,因為下面我們要做的例子,是把ClickOnce同時釋出到本地檔案和IIS伺服器上的。至于如何安裝,請Search the Internet吧。

  1. 以管理者身份運作VS。建立一個Windows窗體應用程式項目。
  2. 把視窗的标題(Text屬性)改成你要的标題,我這裡改為"宇宙無敵應用程式"。然後再拖一個Label控件,把文本改為"超級應用,天下無敵。"。大概就如下圖所示。是不是很霸氣?
ClickOnce部署
  1. 好了,就這樣吧,夠簡單,這就是我們待會兒要釋出的應用程式。
  2. 好,開始釋出ClickOnce安裝程式。打開"解決方案資料總管",在項目節點上右擊,從彈出的快捷菜單中選擇【屬性】,打開項目屬性視窗,切換到"釋出"頁籤。
ClickOnce部署
  1. 如下圖所示,有兩個釋出位置。
ClickOnce部署

釋出位置可以選擇本地檔案夾,也可以選擇IIS上的Web伺服器位址,當然FTP也行。這兩個地方也沒什麼特别,如果你計劃把應用程式直接釋出到本地,就這樣填:

ClickOnce部署

如果你想把安裝程式釋出到伺服器,可以這樣填,也可以單擊右邊的

ClickOnce部署

按鈕來選擇一個位置。

ClickOnce部署

如果你希望在本地檔案目錄中釋出一份,同時又想放到伺服器上讓使用者下載下傳,可以這樣填。

ClickOnce部署
  1. 安裝模式一般選擇第二項,不用解釋,看字面意思就明白了,如下圖。
ClickOnce部署
  1. 我們的程式一般來說不可能是"終極"版,通常我們會不斷更新或更新,是以,在"釋出"頁面中,我們可以單擊"更新"按鈕,随後會彈出一個視窗,如下圖。
ClickOnce部署

我們可以設定應用程式在什麼時候檢查更新,這裡我改為每次運作時都檢查更新。

ClickOnce部署

擷取更新位置,可填可不填,通常與釋出位置相同。

ClickOnce部署

點選确定按鈕,關閉視窗。

  1. 釋出版本号,勾選"随每次釋出自動遞增修訂号"。這樣一來,我們既可以自己填寫版本号,如果忘記修改,也可以自動更新。
ClickOnce部署
  1. 單擊"釋出向導"按鈕,打開向導視窗,這裡我們可以重新設定釋出位置。
ClickOnce部署
  1. 單擊下一步,選擇一種安裝來源。
ClickOnce部署

我們前面設定了IIS伺服器的位置,是以預設是從網站安裝,如果我們的應用程式是刻到CD光牒中來分發給客戶的,也可以選擇從CD/DVD安裝。

  1. 單擊下一步,選擇應用程式的運作方式,如果選擇CD/DVD安裝,則不需要此步。
ClickOnce部署

通常較好的做法是選擇既可以離線使用,也可以在連接配接時使用。

  1. 單擊下一步,再單擊完成按鈕,這時候我們會看到VS正在釋出ClickOnce應用程式。
ClickOnce部署

隻要看到"釋出成功"四個字就說明大功告成了。

下面我們來測試一下。

本地安裝:我們上面的例子是生成了兩個ClickOnce安裝程式的,一個在本機檔案中,一個在IIS伺服器上。找到釋出後的本地目錄,如上面的d:\MyPublic\。輕按兩下setup.exe或MyApp.application檔案,都可以啟用安裝程式。

ClickOnce部署

我們看到,出現安全提示,如果确定應用程式來源合法,可以點選"安裝"按鈕進行安裝。

安裝成功後,我們的超級應用程式就運作起來了。

ClickOnce部署

既然是叫ClickOnce了,那為什麼我們剛才Click了不止一次呢? 那是因為缺少可信任的釋出者證書導緻出現安全提示的。在下一節中,我們會介紹如何自己制作證書,并在客戶計算機中安裝證書,那時候大家就會看到真正的ClickOnce,隻要Click一下就可以安裝了。

現在,我們可以打開"程式和功能"控制台把應用程式解除安裝掉。

網站安裝:打開浏覽器,輸入剛才釋出的Web位址,在後面加上一個.application字尾的檔案名。比如我們這個例子的清單檔案叫MyApp.application。但我們會發現,找不到資源。

打開伺服器上的目錄一看,裡面竟然是空的,我暈。

沒關系,我們隻要把剛才的釋出選項改一下就行了。

ClickOnce部署

然後重新釋出就可以了。

ClickOnce部署

我們看到,安裝程式可以被激活了。

無論是哪種方式釋出,無非就是把安裝給客戶,然後安裝到他們的機器上罷了,是以,大家覺得哪種做法最簡單就用哪種。這些東西也沒有說什麼硬性的條條框框,一切都是技巧而已。

(2):自動更新

上次我們說了如何用最基本的方式用ClickOnce技術部署應用程式項目,本篇我們來認識一下如何讓應用程式具備自動更新的功能。

我們依然通過執行個體來學習。

第一步,随便建一個應用程式項目,至于是控制台、WPF還是WinForm就随意吧,我們的重點釋出應用程式。比如這樣:

ClickOnce部署

為了更好的示範,我們可以在視窗上顯示目前釋出的版本号。我這裡是一個WinForm項目,故我就用一個Label控件來顯示目前釋出版本。

注意,這裡的版本号是ClickOnce釋出的版本号,不是程式集的版本号。是以要使用ApplicationDeployment類(位于System.Deployment.Application命名空間,在程式集System.Deployment.dll中,如果沒有引用,就引用吧)。通過靜态屬性CurrentDeployment可以得到一個與目前部署的應用程式有關的ApplicationDeployment對象。然後從ApplicationDeployment的CurrentVersion屬性中就能得到目前版本号。代碼如下,至于寫在哪個地方,你自己想想吧,這是很基礎的事了。

using System.Deployment.Application;

……

public partial class Form1 : Form

{

public Form1()

InitializeComponent();

// 擷取目前部署

ApplicationDeployment appd = ApplicationDeployment.CurrentDeployment;

// 取得版本号

this.lblVer.Text = appd.CurrentVersion.ToString();

}

好,OK,現在我們可以釋出該應用程式了,因為我們要讓它能夠自動更新,一來我們要釋出到IIS或其他伺服器上,記得以管理者身份運作VS,不然釋出不上去;另外,要開啟檢查更新功能,上一節中說過,操作也很簡單。

在項目屬性視窗中,切換到"釋出"頁籤,單擊"更新…"按鈕,啟用檢查更新即可,至于如何更新,按照預設就可以了,沒有必要去改了。

ClickOnce部署

然後确定,這樣就算配置好了。然後釋出到伺服器上。

第二步,通過浏覽器輸入位址,安裝并運作應用程式,如下圖所示,注意現在的版本是1.0.0.0。

ClickOnce部署

第三步,關閉應用程式,回到VS,我們把剛才的程式改一下,來模拟更新。比如我在視窗上再加一個按鈕,如下圖。

ClickOnce部署

第四步,同樣,打開項目屬性中的"釋出"頁籤,再釋出一次。

我們看到修訂版本号變成1了。

ClickOnce部署

然後直擊點選下面的"立即釋出"按鈕即可。

第五步,釋出成功後,從"開始"中再次運作剛才安裝的應用程式,會看到提示更新的對話框。

ClickOnce部署

點選确定,就會自動下載下傳并安裝更新。這時候我們看到版本号是1.0.0.1了。

ClickOnce部署

(3):使用證書

在講述證書的使用前,我們先來了解另外一個知識——釋出網頁。

在前面所說的ClickOnce部署中,如果大家細心的話,應該會發現這麼個問題。

ClickOnce部署

如上圖,釋出成功後,在"輸出"視窗中提示無法檢視釋出網頁。

好,我們先不管那是什麼,現在我們不妨釋出一個項目,但在"項目屬性"視窗中的"釋出"頁籤上,點選"選項"按鈕,打開"釋出選項"對話框。

在"說明"頁中輸入基本資訊,産品名稱和釋出者。

ClickOnce部署

然後進入到"部署"頁,在部署網頁處輸入一個頁面名稱,最好用index.htm或default.htm之類的名字,因為IIS等伺服器的預設頁面通常是這些。并且勾選"每次釋出後都自動生成部署網頁"項。

ClickOnce部署

單擊确定回到釋出頁,然後我們點選一下"立即釋出",仔細觀察。這一次我們發現,"輸出"視窗不再提示無法打開部署頁面了,而且釋出完成後打開了一個頁面,就是我們剛才輸入的釋出網頁,是VS為我們自動生成的。

ClickOnce部署

我們可以用VS或其他網頁編輯工具來修改這個頁面,一旦我們修改後,記得回到項目屬性中的釋出頁,再次打開釋出選項對話框,去掉"每一次釋出後自動生成部署網頁"項前面的對勾,不然,你所修改的頁面在下一次釋出後會被自動生成的頁面所覆寫。

ClickOnce部署

好,這段内容就說到這兒。下面開始我們的正題。

大家還記得這個界面不?

ClickOnce部署

我們在安裝ClickOnce應用程式的時候,都會彈出這個安全警告,雖然點選"安裝"就可以開始安裝,但是,這就變成不是ClickOnce了,而是ClickTwice了,是吧,我們至少點選了兩下。

這是由于沒有識别到受信任的證書造成的。下面我們來看看如何自己來做證書。

其實VS在釋出ClickOnce部署時是為我們生成了一個臨時證書的,但這樣不太好控制,我們希望自己來做一個符合我們要求的證書,至少在證書的過期日期上我們可以自己來定。對于我們小開發者或小團隊來說,到證書機構購買證書似乎有點"裝逼"了,反正證書就是用來辨別我們釋出者身份,確定我們的應用安裝包在傳播過程中不被修改,我們倒不如自己弄一個證書更簡便。

在項目屬性視窗中,我們切換到"簽名"頁籤,這裡看到VS生成的臨時證書。

ClickOnce部署

我們來自己做個證書吧,自己給自己頒發證書,非常有榮譽感的。要完成這件事,我們需要用到幾個指令行工具,其實大家網上搜一下,也是有很多相關文章的,這裡我也順便給大家示範一遍。

a、首先粉墨登場的是makecert工具,大家看看它的名字就知道它的長相,有點帥,作用當然是建立一個.cer檔案,即證書檔案。至于是啥類型的證書,純屬理論課,大家維基百科一下就有了。

打開Visual Studio指令行視窗,不要告訴我你找不到,然後我們最好用CD指令修改一下目前目錄,我們希望把建立的檔案放到哪裡就定位到哪裡,我呢計劃把這些榮譽證書檔案放到C:\Users\Admin下,即我的個人目錄。輸入以下指令:

cd %USERPROFILE%\證書

這樣,第一步也完成了,看:

ClickOnce部署

b、用makecert指令生成一個證書檔案my.cer,并且附帶一個密鑰my.pvk。輸入以下指令:

makecert –r –n "CN=老周" –b 10/08/2013 –e 08/11/2016 –sv my.pvk my.cer

ClickOnce部署

按回車後,提示建立密碼,輸入密碼,你喜歡,為了好玩,我這裡用123456789作為密碼。

ClickOnce部署

點選OK按鈕,然後又彈出一個視窗,注意,這個和上面那個不同,上面那個是建立密碼,下面這個是用剛才建立的密碼來建立證書。剛才我設定了123456789,是以這裡還是要輸入123456789,不要輸錯密碼,不然要從頭再來了。

ClickOnce部署

點選OK按鈕,好,證書和私鑰檔案就建立完成了。就是這兩個檔案:

ClickOnce部署

解釋一下,-r參數表示自簽名,說白了就是自己給自書頒發證書,一定要加上-r,-n是證書的名字,通常用你的大名或者你公司的名字,以CN開頭,格式為CN=<your name>,比如我叫老周(本來收小周,就因為叫小周的人太多,是以我叫老周),就用CN=老周。

-b是證書有效期的開始日期,格式mm/dd/yyyy,注意,别寫錯,哪怕你是1月份也不要寫成1,應該寫成01;-e是證書有效期的過期日期,格式和前面一樣。

-sv是建立密鑰檔案,檔案名為*.pvk,-sv要加上,後面你會發現,有用的。

最後就是證書檔案的名字,檔案名為*.cer。

c、證書是生成了,但你會看到VS要的.pfx檔案,不是.cer檔案,是以我們必須轉換,但是沒有工具可以一部到位,是以,我們依次用兩個工具來轉換。

先是用cert2spc,把.cer檔案轉換為.spc檔案,不要問為什麼,到了後面一步你就知道為什麼要轉為.spc檔案了。繼續在指令行中輸入:

Cert2spc my.cer my.spc

完成後我們看到又多了一個檔案:

ClickOnce部署

我們離真相越來越近了,還剩最後一個,我們的.pfx證書就要完工了。最後一步就是把.pvk檔案轉為.pfx檔案。是以用pvk2pfx,繼續在指令行中輸入以下指令:

pvk2pfx -pvk my.pvk -spc my.spc -pfx my.pfx -pi 123456789 –po 123456789 –f

ClickOnce部署

這個工具比較複雜,-pvk指定剛才生成的.pvk檔案;-spc就是剛才生成的.spc檔案;-pfx是要生成的.pfx檔案的名字,-pi是.pvk檔案的密碼,即我們前面建立的123456789,-po是生成的.pfx檔案的密碼,你可以重新設,我這裡還是用123456789。

pfx弄好了,現在我們把它放進VS中。VS解決方案中,可以把<項目名>_TemporaryKey.pfx删了,那個是VS生成的臨時證書,現在我們有自己的證書了,臨時證書就沒用了,我們可以送它去見列甯了。

打開項目屬性視窗,切換到"簽名"頁籤,點選"從檔案選取"按鈕,導入剛才生成的.pfx證書。

ClickOnce部署

然後輸入密碼,密碼就是上面執行pvk2pfx指令時-po參數指定的密碼,我仍使用了123456789。

ClickOnce部署

OK,證書就替換了。

ClickOnce部署

你隻要把剛才的.cer檔案(即證書)發給客戶,客戶在安裝你的ClickOnce包之前先把證書安裝到他的計算中的可信任區域中,然後再去安裝你的應用,就不會有安全提示了。以後你釋出的應用都用這個證書就行了,不過,注意證書不要過期了,過期了就重新生成一個日期較新的。

在客戶的機子上,打開控制台,搜尋"證書",然後打開基于計算機的證書管理器,注意不是基于目前使用者。

ClickOnce部署

打開證書管理,在"受信任的根證書頒發機構"節上右擊,從菜中選擇導入。

ClickOnce部署

在"受信任的釋出者"節上的也用同樣的方法導入一次。随後我們再釋出一次ClickOnce部署包,現在就真正ClickOnce了,一點選就全自動安裝了,沒有安全提示了。

ClickOnce部署

(4):下載下傳多個安裝包

有時候,我們可能會一次性釋出多個安裝包,當然在網頁上多加幾個連結讓使用者逐個安裝也是可取的。不過,也可以弄得更友善些,即使用者先安裝一個,作為一個"引導程式",然後通過這個程式去下載下傳安裝其他應用程式。

我們還是說說真實的例子,這樣好了解一點。假設我開發了兩個應用程式,一個叫App1,另一個叫App2。我把這兩個應用程式同時釋出。

我們可以在IIS伺服器的根目錄下建立兩子目錄,我們分别把這兩個應有程式釋出到這兩個檔案夾下,如下面兩張截圖所示。

ClickOnce部署

第一個應用

ClickOnce部署

第二個應用

最後,重點是如何做這個"引導"安裝包,即我們通過這個應用程式來下載下傳前面兩個應用來安裝。

别急,在開工之前,我想讓大家背書,不多,國小生也能背下來的,總共就兩句話:

第一句:凡是和ClickOnce部署有關的類都位于System.Deployment.Application命名空間下。

第二句:開菜單——做菜——試菜——開飯。

第一句話就不用解釋了,如果你不明白說明你還沒入門。我們把重點放在第二句話,這句話可能大家覺得很搞笑,怎麼好像在做飯啊? 是啊,"民以食為天",做飯很重要。

這裡說的是做這個"引導"安裝應用的步驟,我們要用到InPlaceHostingManager類,它可以實作實時下載下傳安裝應用程式包,不要問我這個類在哪裡,前面叫你背了第一句話。

InPlaceHostingManager類使 用按以下幾步。

第一、new一個InPlaceHostingManager對象,這是廢話。構造函數中我們要傳 一個URI,部署清單的URI,打包ClickOnce後,那個以.application字尾結尾的檔案就是。

第二、開菜單。調用GetManifestAsync方法擷取清單,擷取後,無論成功與否會引發GetManifestCompleted事件,是以在調用方法前要為GetManifestCompleted事件附加處理代碼,這是基礎知識,估計我不必解釋了。

第三、做菜。調用AssertApplicationRequirements方法檢查一下你有沒有這個權限,要明白自己是吃幾碗飯的,如果權限不夠會引發異常,如果力所能及,方法調用後一切正常。一個bool類型的參數表示當權限不足時是否嘗試提升,你懂的。

如果權限檢查通過,調用DownloadApplicationAsync方法就可以下載下傳應用程式了,在這過程中會引發DownloadProgressChanged和DownloadApplicationCompleted,這兩個事件我不說了,你知識怎麼處理了,和使用BackgroundWorker一樣,如果你不懂,請回家好好細讀《C#入門經典》。

第四、試菜。打開"開始"菜單或"開始"螢幕,看看有沒有新安裝應用的快捷方式,如果有,那就下載下傳安裝成功了。

ClickOnce部署

界面是包括兩個Label和兩個ProgressBar,标簽用來顯示文本,進度條當然表示下載下傳的進度。

然後處理Form的Load事件,啟動對App1和App2項目的安裝包的下載下傳和安裝。

public partial class Form1 : Form

InPlaceHostingManager appDown1 = null;

InPlaceHostingManager appDown2 = null;

// uris

Uri app1Uri, app2Uri;

app1Uri = new Uri(AppMain.Properties.Settings.Default.app1);

app2Uri = new Uri(AppMain.Properties.Settings.Default.app2);

appDown1 = new InPlaceHostingManager(app1Uri, false);

appDown2 = new InPlaceHostingManager(app2Uri, false);

private void Form1_Load(object sender, EventArgs e)

// 開始下載下傳第一個應用程式

appDown1.GetManifestCompleted += appDown1_GetManifestCompleted;

appDown1.GetManifestAsync();

// 開始下載下傳第二個應用程式

appDown2.GetManifestCompleted += appDown2_GetManifestCompleted;

appDown2.GetManifestAsync();

void appDown2_GetManifestCompleted(object sender, GetManifestCompletedEventArgs e)

if (e.Error != null)

MessageBox.Show(e.Error.Message); return;

lblSecond.Text = "即将下載下傳" + e.ProductName + "," + e.Version.ToString();

try

appDown2.AssertApplicationRequirements(true);

catch (Exception ex)

MessageBox.Show(ex.Message); return;

appDown2.DownloadProgressChanged += appDown2_DownloadProgressChanged;

appDown2.DownloadApplicationCompleted += appDown2_DownloadApplicationCompleted;

appDown2.DownloadApplicationAsync();

void appDown2_DownloadApplicationCompleted(object sender, DownloadApplicationCompletedEventArgs e)

lblSecond.Text = "下載下傳完成。";

void appDown2_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)

this.progressbarSecond.Value = e.ProgressPercentage;

this.lblSecond.Text = "已下載下傳" + e.BytesDownloaded.ToString() + "位元組,共" + e.TotalBytesToDownload.ToString() + "位元組。";

void appDown1_GetManifestCompleted(object sender, GetManifestCompletedEventArgs e)

MessageBox.Show("出錯:" + e.Error.Message); return;

this.lblFirst.Text = "即将下載下傳" + e.ProductName + "," + e.Version.ToString();

appDown1.AssertApplicationRequirements(true);

MessageBox.Show(ex.Message);

return;

appDown1.DownloadProgressChanged += appDown1_DownloadProgressChanged;

appDown1.DownloadApplicationCompleted += appDown1_DownloadApplicationCompleted;

appDown1.DownloadApplicationAsync();

void appDown1_DownloadApplicationCompleted(object sender, DownloadApplicationCompletedEventArgs e)

lblFirst.Text = "下載下傳完成。";

void appDown1_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)

this.progressbarFirst.Value = e.ProgressPercentage;

this.lblFirst.Text = "已下載下傳" + e.BytesDownloaded.ToString() + "位元組,共" + e.TotalBytesToDownload.ToString() + "位元組。";

而應用安裝包的下載下傳位址,我們放到配置檔案中,以便修改。

打開項目屬性視窗,切換到"設定"頁籤,然後輸入App1的下載下傳位址是http://localhost/App1/App1.application;App2的下載下傳位址是http://localhost/App2/App2.application。

ClickOnce部署

VS會為我們生成相應的屬性,如上面代碼中,我們通過目前應用程式所在的程式集中的.Properties.Settings.Default.app1就可以得到app1的值。

兩個應用項目,加上這個用來安裝其他應用包的程式,共三個,把它們都釋出到指定的路徑下。

用來引導的應用就放到根目錄,使用者隻需安裝這個就可以了,然後利用這個應用程式來安裝其他兩個。

ClickOnce部署

App1放到/App1下。

ClickOnce部署

App2放到/App2下。

ClickOnce部署

釋出完成後,IIS的根目錄如下。

ClickOnce部署

然後安裝根目錄下的"引導"包。安裝後運作應用程式,就會自動下載下傳另外兩個安裝包并自動安裝。

ClickOnce部署

安裝完成了,然後打開"開始"菜單或"開始"螢幕,就能看到三個應用程式了。

ClickOnce部署
ClickOnce部署