ClickOnce部署

(1):一些發佈方式瀏覽器

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

若是你對這些理論的東西不感興趣,不要緊,上面所說起的內容你徹底能夠無視之。咱們只要知道,ClickOnce是一種應用程序部署方式便可。那什麼是部署呢? 咱們不妨查一查詞典,部署的釋義爲安排、佈置等,而放到咱們的應用程序來講,咱們通俗的叫法就是安裝。即把你開發好的應用程序佈置到客戶的計算機上,或者說安裝到客戶的計算機上,這就是部署。服務器

因此咱們能夠說ClickOnce應用程序就是一類安裝包裝,它能夠一步到位進行安裝,而不像咱們所使用的傳統安裝包那樣,要N個"下一步",而後纔是完成。app

也許有人也說,發佈ClickOnce包不是很簡單嗎? 在VS裏面點幾下鼠標就完事了嗎? 你還拿來寫博客幹嘛? 首先,法律並無規定簡單的東西不能拿來寫博客;其次,對於許多初學者朋友來講,我想是有參考價值,至少會有;再者,有些小問題可能你們常常會忽略的。函數

咱們先來發佈一個Windows Forms應用程序,練練手。工具

準備條件:先確保安裝了IIS,若是沒有,就趕忙動手吧,由於下面咱們要作的例子,是把ClickOnce同時發佈到本地文件和IIS服務器上的。至於如何安裝,請Search the Internet吧。學習

  1. 以管理員身份運行VS。新建一個Windows窗體應用程序項目。
  2. 把窗口的標題(Text屬性)改爲你要的標題,我這裏改成"宇宙無敵應用程序"。而後再拖一個Label控件,把文本改成"超級應用,天下無敵。"。大概就以下圖所示。是否是很霸氣?

  1. 好了,就這樣吧,夠簡單,這就是咱們待會兒要發佈的應用程序。
  2. 好,開始發佈ClickOnce安裝程序。打開"解決方案資源管理器",在項目節點上右擊,從彈出的快捷菜單中選擇【屬性】,打開項目屬性窗口,切換到"發佈"選項卡。

  1. 以下圖所示,有兩個發佈位置。

發佈位置能夠選擇本地文件夾,也能夠選擇IIS上的Web服務器地址,固然FTP也行。這兩個地方也沒什麼特別,若是你計劃把應用程序直接發佈到本地,就這樣填:測試

若是你想把安裝程序發佈到服務器,能夠這樣填,也能夠單擊右邊的按鈕來選擇一個位置。網站

若是你但願在本地文件目錄中發佈一份,同時又想放到服務器上讓用戶下載,能夠這樣填。ui

  1. 安裝模式通常選擇第二項,不用解釋,看字面意思就明白了,以下圖。

  1. 咱們的程序通常來講不多是"終極"版,一般咱們會不斷更新或升級,因此,在"發佈"頁面中,咱們能夠單擊"更新"按鈕,隨後會彈出一個窗口,以下圖。

咱們能夠設置應用程序在何時檢查更新,這裏我改成每次運行時都檢查更新。

獲取更新位置,可填可不填,一般與發佈位置相同。

點擊肯定按鈕,關閉窗口。

  1. 發佈版本號,勾選"隨每次發佈自動遞增修訂號"。這樣一來,咱們既能夠本身填寫版本號,若是忘記修改,也能夠自動更新。

  1. 單擊"發佈嚮導"按鈕,打開向導窗口,這裏咱們能夠從新設置發佈位置。

  1. 單擊下一步,選擇一種安裝來源。

咱們前面設置了IIS服務器的位置,因此默認是從網站安裝,若是咱們的應用程序是刻到光盤中來分發給客戶的,也能夠選擇從CD/DVD安裝。

  1. 單擊下一步,選擇應用程序的運行方式,若是選擇CD/DVD安裝,則不須要此步。

一般較好的作法是選擇既能夠離線使用,也能夠在鏈接時使用。

  1. 單擊下一步,再單擊完成按鈕,這時候咱們會看到VS正在發佈ClickOnce應用程序。

只要看到"發佈成功"四個字就說明大功告成了。

 

下面咱們來測試一下。

本地安裝:咱們上面的例子是生成了兩個ClickOnce安裝程序的,一個在本機文件中,一個在IIS服務器上。找到發佈後的本地目錄,如上面的d:\MyPublic\。雙擊setup.exe或MyApp.application文件,均可以啓用安裝程序。

咱們看到,出現安全提示,若是肯定應用程序來源合法,能夠點擊"安裝"按鈕進行安裝。

安裝成功後,咱們的超級應用程序就運行起來了。

 

既然是叫ClickOnce了,那爲何咱們剛纔Click了不止一次呢? 那是由於缺乏可信任的發佈者證書致使出現安全提示的。在下一節中,咱們會介紹如何本身製做證書,並在客戶計算機中安裝證書,那時候你們就會看到真正的ClickOnce,只要Click一下就能夠安裝了。

如今,咱們能夠打開"程序和功能"控制面板把應用程序卸載掉。

 

網站安裝:打開瀏覽器,輸入剛纔發佈的Web地址,在後面加上一個.application後綴的文件名。好比咱們這個例子的清單文件叫MyApp.application。但咱們會發現,找不到資源。

打開服務器上的目錄一看,裏面居然是空的,我暈。

不要緊,咱們只要把剛纔的發佈選項改一下就好了。

而後從新發布就能夠了。

咱們看到,安裝程序能夠被激活了。

不管是哪一種方式發佈,無非就是把安裝給客戶,而後安裝到他們的機器上罷了,因此,你們以爲哪一種作法最簡單就用哪一種。這些東西也沒有說什麼硬性的條條框框,一切都是技巧而已。

 

(2):自動更新

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

咱們依然經過實例來學習。

第一步,隨便建一個應用程序項目,至因而控制檯、WPF仍是WinForm就隨意吧,咱們的重點發布應用程序。好比這樣:

爲了更好的演示,咱們能夠在窗口上顯示當前發佈的版本號。我這裏是一個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,否則發佈不上去;另外,要開啓檢查更新功能,上一節中說過,操做也很簡單。

在項目屬性窗口中,切換到"發佈"選項卡,單擊"更新…"按鈕,啓用檢查更新便可,至於如何更新,按照默認就能夠了,沒有必要去改了。

而後肯定,這樣就算配置好了。而後發佈到服務器上。

 

第二步,經過瀏覽器輸入地址,安裝並運行應用程序,以下圖所示,注意如今的版本是1.0.0.0。

 

第三步,關閉應用程序,回到VS,咱們把剛纔的程序改一下,來模擬升級。好比我在窗口上再加一個按鈕,以下圖。

 

第四步,一樣,打開項目屬性中的"發佈"選項卡,再發布一次。

咱們看到修訂版本號變成1了。

而後直擊點擊下面的"當即發佈"按鈕便可。

 

第五步,發佈成功後,從"開始"中再次運行剛纔安裝的應用程序,會看到提示更新的對話框。

 

點擊肯定,就會自動下載並安裝更新。這時候咱們看到版本號是1.0.0.1了。

 

(3):使用證書

在講述證書的使用前,咱們先來了解另一個知識——發佈網頁。

在前面所說的ClickOnce部署中,若是你們細心的話,應該會發現這麼個問題。

如上圖,發佈成功後,在"輸出"窗口中提示沒法查看發佈網頁。

好,咱們先無論那是什麼,如今咱們不妨發佈一個項目,但在"項目屬性"窗口中的"發佈"選項卡上,點擊"選項"按鈕,打開"發佈選項"對話框。

在"說明"頁中輸入基本信息,產品名稱和發佈者。

而後進入到"部署"頁,在部署網頁處輸入一個頁面名稱,最好用index.htm或default.htm之類的名字,由於IIS等服務器的默認頁面一般是這些。而且勾選"每次發佈後都自動生成部署網頁"項。

單擊肯定回到發佈頁,而後咱們點擊一下"當即發佈",仔細觀察。這一次咱們發現,"輸出"窗口再也不提示沒法打開部署頁面了,並且發佈完成後打開了一個頁面,就是咱們剛纔輸入的發佈網頁,是VS爲咱們自動生成的。

 

咱們能夠用VS或其餘網頁編輯工具來修改這個頁面,一旦咱們修改後,記得回到項目屬性中的發佈頁,再次打開發布選項對話框,去掉"每一次發佈後自動生成部署網頁"項前面的對勾,否則,你所修改的頁面在下一次發佈後會被自動生成的頁面所覆蓋。

 

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

 

 

你們還記得這個界面不?

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

這是因爲沒有識別到受信任的證書形成的。下面咱們來看看如何本身來作證書。

其實VS在發佈ClickOnce部署時是爲咱們生成了一個臨時證書的,但這樣不太好控制,咱們但願本身來作一個符合咱們要求的證書,至少在證書的過時日期上咱們能夠本身來定。對於咱們小開發者或小團隊來講,到證書機構購買證書彷佛有點"裝逼"了,反正證書就是用來標識咱們發佈者身份,確保咱們的應用安裝包在傳播過程當中不被修改,咱們倒不如本身弄一個證書更簡便。

 

在項目屬性窗口中,咱們切換到"簽名"選項卡,這裏看到VS生成的臨時證書。

 

咱們來本身作個證書吧,本身給本身頒發證書,很是有榮譽感的。要完成這件事,咱們須要用到幾個命令行工具,其實你們網上搜一下,也是有不少相關文章的,這裏我也順便給你們演示一遍。

a、首先粉墨登場的是makecert工具,你們看看它的名字就知道它的長相,有點帥,做用固然是建立一個.cer文件,即證書文件。至因而啥類型的證書,純屬理論課,你們維基百科一下就有了。

打開Visual Studio命令行窗口,不要告訴我你找不到,而後咱們最好用CD命令修改一下當前目錄,咱們但願把建立的文件放到哪裏就定位到哪裏,我呢計劃把這些榮譽證書文件放到C:\Users\Admin下,即個人我的目錄。輸入如下命令:

cd %USERPROFILE%\證書

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

 

b、用makecert命令生成一個證書文件my.cer,而且附帶一個密鑰my.pvk。輸入如下命令:

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

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

點擊OK按鈕,而後又彈出一個窗口,注意,這個和上面那個不一樣,上面那個是建立密碼,下面這個是用剛纔建立的密碼來建立證書。剛纔我設置了123456789,因此這裏仍是要輸入123456789,不要輸錯密碼,否則要從頭再來了。

點擊OK按鈕,好,證書和私鑰文件就建立完成了。就是這兩個文件:

解釋一下,-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

完成後咱們看到又多了一個文件:

咱們離真相愈來愈近了,還剩最後一個,咱們的.pfx證書就要完工了。最後一步就是把.pvk文件轉爲.pfx文件。因此用pvk2pfx,繼續在命令行中輸入如下命令:

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

這個工具比較複雜,-pvk指定剛纔生成的.pvk文件;-spc就是剛纔生成的.spc文件;-pfx是要生成的.pfx文件的名字,-pi是.pvk文件的密碼,即咱們前面建立的123456789,-po是生成的.pfx文件的密碼,你能夠從新設,我這裏仍是用123456789。

 

pfx弄好了,如今咱們把它放進VS中。VS解決方案中,能夠把<項目名>_TemporaryKey.pfx刪了,那個是VS生成的臨時證書,如今咱們有本身的證書了,臨時證書就沒用了,咱們能夠送它去見列寧了。

打開項目屬性窗口,切換到"簽名"選項卡,點擊"從文件選取"按鈕,導入剛纔生成的.pfx證書。

 

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

 

OK,證書就替換了。

 

你只要把剛纔的.cer文件(即證書)發給客戶,客戶在安裝你的ClickOnce包以前先把證書安裝到他的計算中的可信任區域中,而後再去安裝你的應用,就不會有安全提示了。之後你發佈的應用都用這個證書就好了,不過,注意證書不要過時了,過時了就從新生成一個日期較新的。

在客戶的機子上,打開控制面板,搜索"證書",而後打開基於計算機的證書管理器,注意不是基於當前用戶。

 

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

 

在"受信任的發佈者"節上的也用一樣的方法導入一次。隨後咱們再發布一次ClickOnce部署包,如今就真正ClickOnce了,一點擊就全自動安裝了,沒有安全提示了。

(4):下載多個安裝包

有時候,咱們可能會一次性發布多個安裝包,固然在網頁上多加幾個連接讓用戶逐個安裝也是可取的。不過,也能夠弄得更方便些,即用戶先安裝一個,做爲一個"引導程序",而後經過這個程序去下載安裝其餘應用程序。

咱們仍是說說真實的例子,這樣好理解一點。假設我開發了兩個應用程序,一個叫App1,另外一個叫App2。我把這兩個應用程序同時發佈。

咱們能夠在IIS服務器的根目錄下新建兩子目錄,咱們分別把這兩個應有程序發佈到這兩個文件夾下,以下面兩張截圖所示。

第一個應用

 

第二個應用

 

最後,重點是如何作這個"引導"安裝包,即咱們經過這個應用程序來下載前面兩個應用來安裝。

別急,在開工以前,我想讓你們背書,很少,小學生也能背下來的,總共就兩句話:

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

第二句:開菜單——作菜——試菜——開飯

第一句話就不用解釋了,若是你不明白說明你還沒入門。咱們把重點放在第二句話,這句話可能你們以爲很搞笑,怎麼好像在作飯啊? 是啊,"民以食爲天",作飯很重要。

這裏說的是作這個"引導"安裝應用的步驟,咱們要用到InPlaceHostingManager類,它能夠實現實時下載安裝應用程序包,不要問我這個類在哪裏,前面叫你背了第一句話。

InPlaceHostingManager類使 用按如下幾步。

 

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

 

第2、開菜單。調用GetManifestAsync方法獲取清單,獲取後,不管成功與否會引起GetManifestCompleted事件,因此在調用方法前要爲GetManifestCompleted事件附加處理代碼,這是基礎知識,估計我沒必要解釋了。

 

第3、作菜。調用AssertApplicationRequirements方法檢查一下你有沒有這個權限,要明白本身是吃幾碗飯的,若是權限不夠會引起異常,若是力所能及,方法調用後一切正常。一個bool類型的參數表示當權限不足時是否嘗試提高,你懂的。

若是權限檢查經過,調用DownloadApplicationAsync方法就能夠下載應用程序了,在這過程當中會引起DownloadProgressChanged和DownloadApplicationCompleted,這兩個事件我不說了,你知識怎麼處理了,和使用BackgroundWorker同樣,若是你不懂,請回家好好細讀《C#入門經典》。

 

第4、試菜。打開"開始"菜單或"開始"屏幕,看看有沒有新安裝應用的快捷方式,若是有,那就下載安裝成功了。

 

界面是包括兩個Label和兩個ProgressBar,標籤用來顯示文本,進度條固然表示下載的進度。

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

public partial class Form1 : Form

{

InPlaceHostingManager appDown1 = null;

InPlaceHostingManager appDown2 = null;

 

// uris

Uri app1Uri, app2Uri;

 

public Form1()

{

InitializeComponent();

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)

{

if (e.Error != null)

{

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

}

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

try

{

appDown1.AssertApplicationRequirements(true);

}

catch (Exception ex)

{

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

 

VS會爲咱們生成相應的屬性,如上面代碼中,咱們經過當前應用程序所在的程序集中的.Properties.Settings.Default.app1就能夠獲得app1的值。

兩個應用項目,加上這個用來安裝其餘應用包的程序,共三個,把它們都發布到指定的路徑下。

用來引導的應用就放到根目錄,用戶只需安裝這個就能夠了,而後利用這個應用程序來安裝其餘兩個。

 

App1放到/App1下。

 

App2放到/App2下。

 

發佈完成後,IIS的根目錄以下。

 

而後安裝根目錄下的"引導"包。安裝後運行應用程序,就會自動下載另外兩個安裝包並自動安裝。

 

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

 

相關文章
相關標籤/搜索