不用VS自带的打包工具,不用InstallShield。用C#自己制作安装程序

时间:2021-12-09 18:41:21

用 C#编程的朋友们,你们是否想过用代码写一个自己开发出来的软件的安装程序呢?你们是否厌烦了 Visual Studio 自带的发布功能的枯燥无味呢?你们是否觉得InstallShield 的界面过于单调呢?今天,我们就来自己写一个真正用 C#编制而成的安装程序!没错,所有的功能都是定制的,自己拷贝程序文件,写入注册表,关联文件类型……随心所欲,你可以让它实现任何功能!(当然,我这里只介绍最关键的安装环节。)

你可能会想:这么复杂的功能,一定只有软件公司用专业的工具才能制成吧?其实不然,今天我们就用短短二十余行代码搞定!复制文件、写入注册表、关联文件,一切应有尽有!

在各位读者阅读之前,我需要首先提示:千万不要把事情想得太复杂,

我们不是精通 Windows 系统内部的程序员,我们也不是能代替整个开发团队的工作者,我们更不是在为哪个国际软件公司制作安装程序,不要期望太高,但足够让你有成就感!

具体步骤,请翻至下一页。

   

以下是实现步骤:

第一步:

当然,同你编的任何一个 C#程序一样,你需要新建一个工程(视习惯,可以是 ConsoleApplication、WinForm 或是 WPF)。为了方便叙述,就把工程名定为 Installer 吧。

第二步:

开始安装之前,一定有些软件的介绍啦,许可条款啦之类的,你就按需求添加上去。

第三步:把程序文件添加到本工程的资源中。如图。 

不用VS自带的打包工具,不用InstallShield。用C#自己制作安装程序

依次点击:工程→Installer 属性→资源→添加资源→现有项。选择你的程序文件。然后可以重命名,也可以保持它原来的名字,但不论它叫什么名字,都要记住,因为稍后会用到。 

不用VS自带的打包工具,不用InstallShield。用C#自己制作安装程序

添加完的效果如下图。 


不用VS自带的打包工具,不用InstallShield。用C#自己制作安装程序

第四步:现在,当用户触发某一事件,程序就要开始安装了!

比如当按下“安装”按钮,敲击了回车……总之是让程序开始执行某一操作了,安装即刻开始。

第五步:现在我们要将程序文件释放到安装目录下(这个安装目录可以是用户自定的,也可以是默认的)。
代码如下:
using System.IO; 
Directory.CreateDirectory("C:/Program Files/Program/");
FileStream writer = new FileStream("C:/Program Files/Program/Program.exe", FileMode.OpenOrCreate);
writer.Write(Properties.Resources.Program, 0, Properties.Resources.Program.Length);
writer.Close();

注意:Properties.Resources.Program 中,Program 就是刚刚添加的资源名称,同理,可以将其他各个文件也导入到相应的路径。但是,

"C:/Program Files/Program/Program.exe"这个文件名一定要写成原名,否则会导致程序集无法引用等问题。

现在开始运行程序。咦?怎么出现异常了呢?不要紧,这是在执行向 “Program Files”文件夹释放文件是没有管理员权限而引起的。那以后就暂时不用Visual Studio 的运行按钮了,先去“Debug”目录下右击→

以管理员身份运行吧!那你就会说了:要是让用户也这样用多麻烦呀!放心,稍后我会介绍解决方法。

第六步:

软件的程序文件安装完了,但是只不过是拷贝了一份文件,并没有向系统中添加信息,接下来我们就要写入注册表。

在介绍具体做法之前,先讲一下 Windows 注册表关于安装软件的部分。

在 命 令 提 示 符 下 输 入 regedit , 即 弹 出 注册 表 编 辑 器 , 依 次 展 开 HKEY_LOCAL_MACHINE → SOFTWARE → Microsoft→ Windows → CurrentVersion → Uninstall。这时我们会看到有许多我们熟悉的软件名。那就对了,这就是在你的计算机上安装过的软件。你可以试着在“Uninstall”中新建键值

“Program”,再在 Program中新建两个字符串值,一个名字是“DisplayName”,值为“Program”;另一个名字是“UninstallString”,值为“Uninstall.exe”。现在去控制面板看看,是不是“卸载程序”页面中多了一个叫做“Program”的程序?

如果你看到了,就说明你操作得很正确其实,“Uninstall”中的键值并不重要,重要的是其中的那两个字符串。“DisplayName”指的是显示出来的程序名称, “UninstallString”指的是卸载程序的路径。当你在控制面板点击卸载时,计算机自动运行“UninstallString”所指示的卸载程序。但是,由于我们现在还没有卸载程序,只能先随便填一个名称(Uninstall.exe)[1];但是绝对不能不填,否则控制面板中不会显示你的这个程序的。

其实除了“DisplayName”、“UninstallString”外,还有很多常用的名称,例如“Publisher”(发布者)、“DisplayVersion”(版本号)等等,这里不再赘述,有兴趣的读者可以自行查阅有关本方面的资料。

既然已经知道了原理,我们现在就要用代码来实现了。

代码如下:
using Microsoft.Win32; 
var key = Registry.LocalMachine.OpenSubKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall", true);
key.CreateSubKey("Program");
key = key.OpenSubKey("Program", true);
key.SetValue("DisplayName", "Program");
key.SetValue("UninstallString", "Uninstall.exe");

运行一下,是不是效果很好?

这 里有 一 点 特 别 需 要 注 意 : 先 观 察 这 个 字 符 串
"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall"

为什么用“\\”而不用“/”呢?这就是规定!我当时研究时一直抛出异常,最后才明白竟然是斜杠用错了!第七步:到现在,一个像模像样的安装程序已经呈现在我们眼前了,最后还有一点需要润色的地方——处理文件关联。

现在设我们这个程序(在我这里是 Program.exe)能够打开的文件类型是.prg。想要达成的操作是:使.prg 文件的“文件类型说明”改为

“Program File”;双击.prg 文件时,自动打开 Program.exe[2]

观察如下代码:
RegistryKey file = Registry.ClassesRoot;
file.CreateSubKey(".prg");
file = file.OpenSubKey(".prg", true);
file.SetValue("", "Program File");
file.CreateSubKey("Shell");
file = file.OpenSubKey("Shell", true);
file.CreateSubKey("Open");
file = file.OpenSubKey("Open", true);
file.CreateSubKey("Command");
file = file.OpenSubKey("Command", true);
file.SetValue("", "C:\\Program Files\\Program\\Program.exe");

各位一定能分析明白我是如何添加文件关联的了吧!双击任何一个.prg文件,是不是你的程序开始运行了?
------------------------------------------------------[1] 在本文中不介绍卸载程序的制作方法,但是相信读者在认真读完本文后,能自己做出一个出色的卸载程序。 [2] 按照我下文的方法处理后,只能实现双击这一类型的文件后运行程序;至于打开文件后程序的处理,还需各读者自己研究。