先说说我的需求:
目前有一个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. 直接贴代码:
///
/// 执行CMD命令
///
/// 命令值
public void RunCmd(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();
}
///
/// 注册Dll到Gac
///
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
gacutil,gac
};
RunCmd(list);
}
///
/// 卸载Gac中的Dll
///
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
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.最后附上我实现的源码 : 单击下载源码