1. 程式人生 > >2018第一發:記一次【Advanced Installer】打包之旅

2018第一發:記一次【Advanced Installer】打包之旅

4.0 config文件 cli 簡單 官網 class 用法 process file

一、前言

2017年最後幾天,你們都高高興興的跨年,博主還在加班制作.net安裝包。因為年前要出來第一版的安裝包,所以博主是加班加點啊。本來想用VS自帶的制作工具,不過用過的人都知道,真是非常好(tong)用(ku),各種包需要單獨下載不說,界面也不美觀,所以決定棄用之。同事推薦用Advanced Installer,不過同事也是很久不用了,記不起來具體用法。所以博主是邊摸索邊前進,所以不免跳進坑裏,為了避免後來人跳進同樣的坑裏,作文以記之。

好了,不說廢話,正文開始!

二、畫流程圖

俗話說的好,“磨刀不誤砍柴工”!

首先強調一點,我們要先弄清楚我們每一步要做什麽,這樣接下來在制作安裝包時才能條理清晰,有條不紊,不容易犯錯。

比如我們要判斷客戶機器上是否安裝.net framework3.5及以上版本,是否安裝IIS,是否安裝SQL Server2005及以上版本數據庫等等。

我這個項目的流程圖如下:

技術分享圖片

Tips1:開始之前最好先畫流程圖

三、開始制作

有了流程圖,只需按部就班!關於Advanced Installer的基礎用法,網上有很多的資料,官網也有幫助文檔,這裏就不贅述了。由於要用到自定義安裝包的過程,需要新建對話框,博主用了企業模板,Advanced Installer的版本是14.5.2,也是最新的版本。

1、選擇模板

首先新建模板裏面選擇Enterprise,並選擇語言(默認為中文),然後創建項目:

技術分享圖片

Tips2:如果安裝包中需要自定義對話框,則需要選擇Enterprise版。

2、設置基本信息

Name即為該安裝包的名稱,公司就是你所在的公司啦,還有版本信息等等,這個很簡單。

技術分享圖片

3、設置默認安裝路徑

點擊Package Definition->Install Parameters,填寫默認安裝路徑。

Application folder默認的內容是這樣:“[ProgramFilesFolder][Manufacturer]\[ProductName]”, 這個內容表示安裝時默認的安裝路徑:

[ProgramFilesFolder]表示文件夾,這裏為D:\Program Files(x86)。

[Manufacturer]表示公司名稱,這裏為Landsoft。

[ProductName]表示產品名稱,這裏為LandaV9。

技術分享圖片

4、設置安裝條件

點擊Requirements->Launch Conditions->Software,勾選相應的條件。這裏根據流程圖所示,我應該勾選.Net Framework、IIS以及SQL Server。註意這裏的條件指的是最低條件,比如我這裏SQL Server選的是2005,即客戶機器上應該裝有2005及以上版本的SQL Server,如果沒有裝,則會提示沒有安裝SQL2005。

這裏還有系統條件即要求客戶機器是win7還是winxp等等。如果還有更多的條件,Custom裏面可以自定義。

技術分享圖片

5、添加文件或文件夾

點擊Resources->Files and Folders,在Application Folders上右鍵,選擇Add Folder或者Add Files,這裏我添加了5個文件夾,用於後續操作。

技術分享圖片

6、自定義對話框(Dialog)

新建對話框之前可以在Themes中選擇主題和樣式。

點擊User Interface->Dialogs,在FolderDlg上右鍵,選擇Add Dialog是添加Advanced Installer中自定義的對話框,選擇New Dialog是新增一個空的對話框,

然後我們可自行在上面定義內容:

技術分享圖片

新建對話框後,可以拖出安裝過程中dialog的外觀,這個對於我們.Net開發人員來說,應該是小Case吧,看一下效果:

技術分享圖片

可以對文本框設置默認值:

技術分享圖片

Tips3:文本框中的屬性名,不要修改。如果修改會有大問題,至於什麽問題,後面再說!

由於我們需要設置連接字符串,所以需要客戶設置數據庫的相關信息:

選擇Add Dialog後,在彈出框中選擇SQLServerConnentionDlg

技術分享圖片

效果如下:

技術分享圖片

最後再新建一個對話框,用於部署項目到IIS所需要的條件:

技術分享圖片

同樣可以設置網站名稱和端口號:根據流程圖,這裏的默認值需要分別設置為Mango和8001,用戶可以自行修改。

到這裏新建對話框告一段落。

7、設置必填驗證

就拿上面這個對話框為例,雖然我們設置的有默認值,但是客戶在安裝過程中不小心給刪掉了,又沒有填寫,恰巧又點了下一步,這樣的話,安裝過程中會有問題。所以我們要做必填驗證,即文本框中沒有值,則“下一步”按鈕不可用,有值才可用。

所以選擇“下一步”,關註下方的“Control Conditions”:

技術分享圖片

點擊New按鈕在新彈出的界面中在Condition中填寫“NOT EDIT_1_DROP OR NOT EDIT_1_DROP_1”,在Action中選擇Disable。

EDIT_1_DROP和EDIT_1_DROP_1就是網站名稱和端口號,前面加NOT的意思就是,如果這兩個文本框中任意一個沒有填寫,則按鈕不可用(Disable)。

同理再添加一個“EDIT_1_DROP AND EDIT_1_DROP_1”,在Action中選擇Enable。即都填內容了,則按鈕可用。這樣就對控件做了必填驗證。是不是很簡單呢!

技術分享圖片

8、設置桌面快捷方式

根據流程圖所示,安裝結束後,需要在桌面生成快捷防方式。所以接下來,我們就來做這件事:

技術分享圖片

首先來到Files and Folders選項卡,在Application Shortcut Folder上面右鍵 選擇“New Shortcut”,彈出如下界面:

技術分享圖片

在這個框裏主要設置快捷方式的Name和描述以及圖標(這個圖標,可以選擇.exe文件)。點擊OK,就會在Application Shortcut Folder中顯示這樣一條信息。

技術分享圖片

但是先別急,如果僅僅是這樣的話,快捷方式是不起作用的。因為我們還沒有設置快捷方式對應的可執行文件。

雙擊這條信息,在彈出的對話框中設置Shortcut Target。

技術分享圖片

看到這,肯定有人有疑問?既然這樣為什麽不在新增快捷方式的時候一起設置呢?

因為在新增的時候,Shortcut target這個文本框中的內容不能修改。這個很坑爹,博主也試了好久才試出來的。

最後,將這個信息拖到Desktop裏面即可,安裝完畢後,就會在桌面顯示這個快捷方式。

技術分享圖片

四、設置IIS網站的網站名、端口號

在上面對話框的最後一步中,我們記住網站名稱的和端口號的文本框的屬性名,然後來到IIS選項卡中:

首先新增一個應用程序池,名稱即為網站名稱文本框的屬性名,這裏為EDIT_1_PROP,在Advanced Installer裏面,使用中括號[]將控件的屬性名括起來表示變量的概念。

在Basic Pool Settings中設置程序池的啟動模式為總是啟動,勾選立即啟動程序池復選框,framework版本選擇為4.0,托管模式選擇為集成。

技術分享圖片

在Identity中設置應用程序池表示為ApplicationPoolIdentity。

技術分享圖片

應用程序池設置好之後,再來設置站點:

新建一個站點名稱同樣為EDIT_1_PROP,在Basic Site Setting中設置Name和文件路徑。

技術分享圖片

在Bindings/SSL中設置端口號,IP地址選擇全部未分配。

技術分享圖片

在Application Pool中選擇剛剛新建的應用程序池。

技術分享圖片

到這裏IIS這一塊就設置好了。

安裝過程中,Advanced Installer就會自動的將網站部署好。這個真的是很牛很強大!不得不佩服人家做的就是好!

五、兩種方式設置config文件

1、直接在Advanced Installer中設置

在添加文件的時候,如果有xml類型的文件,會有這樣的提示:

技術分享圖片

這時候我們勾選需要修改配置的文件,點擊ok,這樣就可以直接在Advanced Installer中修改。

找到需要修改的節點,直接有文本框的屬性替換掉就可以:

技術分享圖片

這樣,在安裝過程中就會將config文件中的相應的節點替換為客戶輸入的值。

還記得Tips3嗎?我們說過如果修改文本框的屬性名之後,那麽這樣設置之後,config中的值不會設置為客戶輸入的值,會始終是文本框中設置的默認值。

切記切記!!!重要的事情三個嘆號!

2、使用自定義的dll文件

關於這點請見第六小節。

六、自定義dll

點擊Custome Behavior->Custom Actions,選擇.Net Installer Class action。這時會讓你選擇文件中的dll文件。

技術分享圖片

當然了,在此之前,請打開你的Visual Studio,新建一個類庫項目,這裏命名為InstallLandaV9ServiceT,然後新建一個安裝程序類,重寫Install方法。

到這裏,我們先暫停一下,問一下自己:在程序中怎麽接收從Advanced Installer傳過來的參數呢?

假如此時我們已經將這個dll加入到Advanced Installer中,在Installer Class Paramters中可以添加參數。

技術分享圖片

比如將文件路徑傳到後臺,可以這樣添加:Name為FilePath,Value為[APPDIR]\。

這裏有地方需要註意,傳遞文件路徑時,Value為[APPDIR]\,這個"\"請不要漏掉了。

Tips4:傳遞文件路徑時,Value為[APPDIR]\,這個"\"請不要漏掉了。

其他參數的Value,需要設置為對應文本框的屬性名稱,格式為:[屬性名]。

下面來看一看代碼:

public override void Install(IDictionary stateSaver)
{
    Parameters configParms = new Parameters();
    configParms.FilePath = Context.Parameters["FilePath"];
    configParms.ServerPath = Context.Parameters["ServerPath"];
    configParms.ClientPath = Context.Parameters["ClientPath"];
    configParms.DataSource = Context.Parameters["DataSource"];
    configParms.UserId = Context.Parameters["UserId"];
    configParms.Password = Context.Parameters["Password"];
    new Operators().UpdateLandaV9Config(configParms);
    base.Install(stateSaver);
}

這裏主要接收從Advanced Installer中傳過來的參數,接著在Operators類中更新配置文件。

還記得Tips3嗎?如果在那裏修改的屬性名,那麽這裏接收的參數也是文本框的默認值。

這裏面主要幹了三件事,獲取連接字符串,更新連接字符串,安裝服務

public void UpdateLandaV9Config(Parameters configParms)
{
    string filePath = Path.Combine(configParms.FilePath, "LandaV9Service", "LandaEntryInfoService.exe.config");
    string connectionString = this.GetConnectionString(configParms);
    this.UpdateConnections(filePath, connectionString);this.InstallService(Path.Combine(configParms.FilePath, "LandaV9Service"));
}

還記得Tips4嗎?如果在傳遞文件路徑的時候只是寫[APPDIR],而不是[APPDIR]\,那麽程序運行到這裏的時候,會拋“FileNotFound”異常!

下來來看一下具體的代碼:

/// <summary>
/// 獲取連接字符串
/// </summary>
/// <param name="op"></param>
/// <returns></returns>
public string GetConnectionString(Parameters op)
{
    return string.Format("Data Source={0};Initial Catalog=LandaEntryManager;Persist Security Info=True;User ID={1};Password={2}", op.DataSource, op.UserId, op.Password);
}

/// <summary>
/// 更新連接字符串
/// </summary>
/// <param name="filePath"></param>
/// <param name="conn"></param>
public void UpdateConnections(string filePath, string conn)
{
    XmlDocument xmlDocument = new XmlDocument();
    xmlDocument.Load(filePath);
    XmlElement xmlElement = (XmlElement)xmlDocument.SelectSingleNode("/configuration/connectionStrings/add[@name=‘LandaEntryManager‘]");
    if (xmlElement != null)
        xmlElement.SetAttribute("connectionString", conn);
    xmlDocument.Save(filePath);
}

再來看安裝服務:

/// <summary>
/// 安裝服務
/// </summary>
/// <param name="filePath"></param>
public void InstallService(string filePath)
{
    Environment.CurrentDirectory = filePath;
    Process process = new Process();
    process.StartInfo.UseShellExecute = false;
    process.StartInfo.FileName = "Install.bat";
    process.StartInfo.CreateNoWindow = true;
    process.StartInfo.Verb = "runas";  //主要設置為以管理員啟動
    process.Start();
}

有安裝就有啟動,可是如果緊跟其後寫啟動服務,會提示找不到服務,安裝程序就會出錯。

博主想了一個辦法,重寫OnAfterInstall方法,在這個方法裏面寫啟動服務:

/// <summary>
/// 重啟服務
/// </summary>
/// <param name="savedState"></param>
protected override void OnAfterInstall(IDictionary savedState)
{
    ServiceController serviceController = new ServiceController("LandaInformationServiceV9");
    serviceController.Start();
    base.OnAfterInstall(savedState);
}

這樣就沒問題了!

在這個程序集裏面可以自定義你想做的其他事情,比如,還原數據庫等等。

七、後記

本次教程到此結束,這也是博主在這幾天假期摸索出來的,如果有不當之處,盡請指正!

附上Advanced Installer的官網地址:https://www.advancedinstaller.com/。

希望本文對你有所幫助。如果你覺得本文能夠幫助你,就點個贊吧。你的支持是博主繼續堅持的不懈動力。

2018第一發:記一次【Advanced Installer】打包之旅