先說說我的需求:
目前有一個winform程序,需要製作一個安裝包,關鍵是在程序安裝完畢後將安裝目錄下的一個 dll註冊到gac 中。
接下來一步一步走
1. 新建項目—選擇左側其他項目類型下的安裝和部署中的Visual Studio Installer – 選擇右側的安裝項目,選好路徑,設置名稱單擊確定
2. 在當前項目右鍵視圖—文件系統--應用程序文件夾上右鍵 添加—文件,選擇需要部署winform程序debug下的所有文件,然後添加一個msiexec.exe文件,該文件路徑在C盤—Windows—System32下(卸載程序用),同時添加一個啓動程序的icon圖標和一個卸載的icon圖標
3. 將程序顯示在開始菜單中:在當前項目右鍵視圖—文件系統—用戶的”程序”菜單,添加一個文件夾,取程序相關的名稱,然後在該文件夾下右側右鍵 – 創建新的快捷方式—在雙擊應用程序文件夾的可執行程序 單擊確定,這個作爲啓動程序,然後再添加一個快捷方式,選擇應用程序文件夾下的msiexec.exe作爲卸載程序,名字可隨意改.
4. 將程序顯示在用戶桌面中:在當前項目右鍵視圖—文件系統—用戶桌面,添加快捷方式,選擇應用程序文件夾的可執行程序.
5. 設置啓動程序和卸載程序的圖標:在剛設置的啓動程序和卸載程序中,右鍵,屬性窗口,其中有個Icon屬性,選擇應用程序文件夾下您添加的對應的圖標.
6. 實現卸載程序:在當前項目右鍵視圖—文件系統—用戶的”程序”菜單—您剛添加的名稱—卸載程序—右鍵屬性窗口—其中有個屬性 Arguments 設置值爲 /x {4458FCB5-91C5-4FFC-8B15-E636FB452220},後面括號中的一串是怎麼得到的呢,單擊當前項目,查看屬性窗口,注意不是項目右鍵中的屬性,這是2個不同的。其中有個ProductCode 對,就是這個,Copy過去。
7. 以上基本實現了安裝和卸載,但是最關鍵的是,我還需要註冊DLL到GAC呢.
8. 在當前解決方案中新建項目—選擇C#類庫,單擊確定,刪除默認的Class1.cs類,在該類庫中右鍵添加新項搜索安裝程序類,取個名字,單擊確定
9. 接下來就寫代碼實現註冊DLL到GAC中了。
10. 重載2個方法:OnAfterInstall()和Uninstall(),前面這個是安裝時用的,後面這個是卸載時用的。其中需要獲取用戶的安裝目錄路徑,可通過this.Context.Parameters["targetdir"].ToString() 得到。這個targetdir參數 稍後會配置.
11. 直接貼代碼:
///<summary>
/// 執行CMD命令
/// </summary>
/// <param name="list">命令值</param>
public void RunCmd(List<string>list)
{
//**用命令方式啓動gacutil.exe
Process p = new Process();
p.StartInfo.FileName ="cmd.exe";
p.StartInfo.UseShellExecute =false;
p.StartInfo.RedirectStandardInput =true;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.RedirectStandardError =true;
p.StartInfo.CreateNoWindow = true;
p.Start();
//**填寫執行命令
foreach (string item in list)
{
p.StandardInput.WriteLine(item);
//**執行命令
}
p.StandardInput.WriteLine("exit");
p.StandardOutput.ReadToEnd();
}
/// <summary>
/// 註冊Dll到Gac
/// </summary>
public void RegDllGac()
{
//**需加雙引號
string gacutil = String.Empty;
//**先找到gacutil的文件夾
if(!Environment.Is64BitOperatingSystem)
gacutil = "cd \"C:\\Program Files\\Microsoft SDKs\\Windows\\v7.0A\\bin\\NETFX 4.0Tools\"";
else
gacutil = "cd \"C:\\Program Files (x86)\\Microsoft SDKs\\Windows\\v7.0A\\Bin\\NETFX 4.0Tools\"";
string gac = "gacutil -i \"" + this.Context.Parameters["targetdir"].ToString() +"/SAEVP.ModuleWizard.dll\"";
List<string> list = newList<string>() {
gacutil,gac
};
RunCmd(list);
}
/// <summary>
/// 卸載Gac中的Dll
/// </summary>
public void UnInstallDllGac()
{
//**需加雙引號
string gacutil = String.Empty;
//**先找到gacutil的文件夾
if(!Environment.Is64BitOperatingSystem)
gacutil = "cd \"C:\\Program Files\\Microsoft SDKs\\Windows\\v7.0A\\bin\\NETFX 4.0Tools\"";
else
gacutil = "cd \"C:\\Program Files (x86)\\Microsoft SDKs\\Windows\\v7.0A\\Bin\\NETFX 4.0Tools\"";
string gac = "gacutil -u \"SAEVP.ModuleWizard, Version=1.0.0.0, Culture=neutral,PublicKeyToken=b7f931a495d236a4\"";
List<string> list = newList<string>() {
gacutil,gac
};
RunCmd(list);
}
protected override voidOnAfterInstall(IDictionary savedState)
{
if (savedState == null)
{
Console.WriteLine("IDictionary 丟失");
}
else
{
base.OnAfterInstall(savedState);
try
{
RegDllGac();
}
catch (Exception ex)
{
throw newException(ex.ToString());
}
}
}
public override voidUninstall(IDictionary savedState)
{
if (savedState == null)
{
Console.WriteLine("IDictionary 丟失");
}
else
{
base.Uninstall(savedState);
try
{
UnInstallDllGac();
}
catch (Exception ex)
{
throw newException(ex.ToString());
}
}
}
12. 其中實現的方式:就是通過調用CMD 找到Gacutil.exe的位置用gacutil.exe命令來註冊DLL到GAC中,同時也通過Gacutil.exe 卸載GAC中的程序集。
13. 接下來就要在安裝項目與之做關聯了。
14. 在當前項目右鍵視圖—文件系統--應用程序文件夾—右鍵—添加—項目輸出,在彈出的框中,選擇剛創建的類庫,選擇主輸出,單擊確定。
15. 在當前項目右鍵視圖—自定義操作—安裝—添加自定義操作—應用程序文件夾—主輸出來自“類庫的名字” (活動),單擊確定。
16. 還記得前面的targetdir 參數嗎,在當前項目右鍵視圖—自定義操作—安裝—主輸出來自“類庫的名字”(活動),右鍵屬性窗口,屬性窗口中有個 CustomActionData參數:賦值爲:/targetdir="[TARGETDIR]\" 注意這個值中的雙引號;不能丟失哦。否則安裝過程中會報
此類錯誤
17. 註冊成功後在哪裏看呢: C:\Windows\Microsoft.NET\assembly\GAC_MSIL 這個裏面 就有剛註冊的DLL
18. 在卸載中照一步操作。爲啥呢:卸載的時候我想把安裝時註冊DLL的GAC中的給卸載掉。
19. 功能差不都都實現了;但是有個前提是需要電腦中有.net framework 4.0
20.最後附上我實現的源碼 : 單擊下載源碼