C#桌面应用程序制作成安装包

Posted freedom0221

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C#桌面应用程序制作成安装包相关的知识,希望对你有一定的参考价值。

 

前言
C#写好一个应用程序,总想分享给自己的朋友或者上架,然而被困在打包之外,这次为大家带来近期我的经验,经过几天的摸索,发现网上的教程并不全面,会给初学者带来很多疑问,这里将做些问题描述与解答。
/**
开发工具:Visual Studio 2017 (这个可以忽略)
系统版本:win10 x64
要求:已经有一个已完成的项目
*/

1.获取打包工具,使用微软自带工具,获取步骤如下,若已安装请忽略此步。
打开工具->扩展和更新->搜索(2017 installer)->点击安装:

 技术图片

 

 

 技术图片

 

这里安装扩展的具体步骤就不再赘述。
2. 安装完扩展以后,新建一个Setup project项目。

技术图片

 

界面如下

 

技术图片

 


“应用程序文件夹”即”Application Folder”表示要安装的应用程序需要添加的文件;
“用户的‘程序’菜单”即”User’s Programs
Menu”表示:应用程序安装完,用户的“开始菜单”中的显示的内容,一般在这个文件夹中,需要再创建一个文件用来存放:应用程序.exe和卸载程序.exe;
“用户桌面”即”User’s Desktop”表示:这个应用程序安装完,用户的桌面上的创建的.exe快捷方式。
3. 解决方案->添加->新建项目->类库,命名为ClassLibrary,在项目ClassLibrary下面,删除Class1.cs,添加->新建项目->安装程序类(名称为InstallerDemo.cs),打开Installer,这个class Installer继承自System.Configuration.Install.Installer,里面就一个构造函数。现在安装程序不能完成的功能,都可以在这个类写代码来自己实现。
4. 重写安装函数BeforeInstall,AfterInstall,AfterRollback,AfterUninstall,BeforeRollback,BeforeUninstall等复制以下代码实现自定义操作:
ps:这里的OnAfterInstall操作是写入注册表,自启动

protected override void OnAfterInstall(IDictionary savedState)

LogWrite("OnAfterInstall!");
string path = this.Context.Parameters["targetdir"];//获取用户设定的安装目标路径, 注意,需要在Setup项目里面自定义操作的属性栏里面的CustomActionData添加上/targetdir="[TARGETDIR]\\"
LogWrite(path); //开机启动
RegistryKey hklm = Registry.LocalMachine;
RegistryKey run = hklm.OpenSubKey(@"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run",true);

try
//64位系统在计算机\\HKEY_LOCAL_MACHINE\\SOFTWARE\\WOW6432Node\\Microsoft\\Windows\\CurrentVersion\\Run
LogWrite("设置注册表!");
LogWrite(path.Substring(0, path.Length - 1) + @"BingPic\\BingPic.exe");
run.CreateSubKey("Bing",true);
run.SetValue("Bing", path.Substring(0,path.Length-1) + @"BingPic\\BingPic.exe");
hklm.Close();
LogWrite("设置结束!");


catch (Exception my)

my.ToString();
LogWrite(my.ToString());

base.OnAfterInstall(savedState);

public override void Install(IDictionary stateSaver)

LogWrite("Install!");
base.Install(stateSaver);

protected override void OnBeforeInstall(IDictionary savedState)

LogWrite("OnBeforeInstall!");
base.OnBeforeInstall(savedState);

public override void Uninstall(IDictionary savedState)

LogWrite("Uninstall!");
base.Uninstall(savedState);

public override void Rollback(IDictionary savedState)

LogWrite("Rollback");
base.Rollback(savedState);

public void LogWrite(string str)

string LogPath = @"c:\\log\\";
using (System.IO.StreamWriter sw = new System.IO.StreamWriter(LogPath + @"SetUpLog.txt", true))

sw.WriteLine(DateTime.Now.ToString("[yyyy-MM-dd HH:mm:ss] ") + str + "\\n");


 

实现以上还不能应用到你的程序中,接下来添加主程序入口。
5. 添加主程序入口:“application folder 应用程序文件夹”–右侧空白处右键–“添加”–“项目输出”


技术图片

 


项目Setup1 ->添加->项目输出->选择ClassLibrary后确定,你会发现,在项目Setup1 下面多了一项“主输出来自ClassLibrary(活动)”的字样。

技术图片

 


6. 添加自定义操作: 可以看到四个子项:安装,提交,回滚,卸载。在安装上面点击右键->添加自定义操作->选择“主输出来自ClassLibrary(活动)”。这样,重新生成后,安装之后就会执行 OnAfterInstall代码了。
技术图片

 

 


ps:获取用户设定的安装目标路径, 注意,需要在Setup项目里面自定义操作->install->输出的属性栏里面的CustomActionData添加上/targetdir=”[TARGETDIR]\\”这样代码里就可以获取到安装路径了

 


7. 添加卸载程序:c:\\windows\\system32\\msiexec.exe

 


获取资源管理器”:点击项目setup1,属性>-“ProductCode” ,将它的值复制,后面需要使用,很重要。

 

8. 添加你的已存在项目文件:debug目录下的文件添加到应用程序文件夹里。

 


9. 创建应用程序快捷方式,卸载快捷方式.并重命名为你希望的,剪切并黏贴到桌面文件夹和用户程序文件夹

 

技术图片

 


并在卸载快捷方式的属性中添加之前复制的

技术图片

 


最后生成应用程序即可。

技术图片

 


至此你的第一个应用程序就打包好了。现在去测试吧!

技术图片

 

这个例子中在写入注册表时遇到了不少难题,其中一个很迷惑人的就是:
System.UnauthorizedAccessException: 无法写入到注册表项。
在 System.ThrowHelper.ThrowUnauthorizedAccessException(ExceptionResource resource)
在 Microsoft.Win32.RegistryKey.EnsureWriteable()
在 Microsoft.Win32.RegistryKey.SetValue(String name, Object value, RegistryValueKind valueKind)
在 Microsoft.Win32.RegistryKey.SetValue(String name, Object value)
在 MyInstall.InstallerBing.OnAfterInstall(IDictionary savedState)
后来找资料说是未将RegistryKey run = hklm.OpenSubKey(@”SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run”,true);设为true,之后解决。

操作注册表时还有一个问题就是写入成功,找不到的问题,
在32位机上自启动路径位:计算机\\HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run
64位:计算机\\HKEY_LOCAL_MACHINE\\SOFTWARE\\WOW6432Node\\Microsoft\\Windows\\CurrentVersion\\Run

最后设置的CustomActionData添加上/targetdir=”[TARGETDIR]\\”,一定要写对 /targetdir=”[TARGETDIR]\\”

欢迎大家指出问题。
---------------------

 

以上是关于C#桌面应用程序制作成安装包的主要内容,如果未能解决你的问题,请参考以下文章

VS2008如何将C#写的Winform程序打包成安装包?

WPF程序如何打包成安装包或者exe文件?bin\debug里面没有exe,我要在VS2015或者12打包,怎么弄,在线等急

C# Winform 生成安装软件

使用vs将应用程序打包成安装包,并设置图标卸载程序等

如何打包WPF安装程序成一个文件

Windows服务项目打包成安装包(Windows服务)-----------VS2017项目程序打包成.msi或者.exe