使用 Visual Studio 2010 安装项目创建 C# Windows 应用程序的 MSI/安装程序包






4.88/5 (90投票s)
在本文中,我想用非常简单的方式,一步一步地解释如何创建一个 Windows 应用程序以及相应的安装程序,以便于理解和遵循。要知道,有许多其他方法可以完成同样的事情。
引言
微软提供了多种方法来为 Windows 应用程序创建安装项目。
但是,当我开始创建时,我却满脑子都是如何开始和从哪里开始的疑问和困惑。我找到了许多解释如何创建安装项目的文章,但有些不起作用,有些没有实际的示例可供参考。
促使我写这篇文章的动力是我的 QC 团队,他们接受了主要应用程序进行测试,并且他们也以 100% 的努力验证了我的安装程序。猜怎么着,他们也从中发现了 bug。
在本文中,我想用非常简单的方式,一步一步地解释如何创建一个 Windows 应用程序以及相应的安装程序,以便于理解和遵循。要知道,有许多其他方法可以完成同样的事情。
开始演示
首先,让我们创建一个只有一个文本框和一个按钮的简单单窗体 Windows 应用程序。
创建 Windows 应用程序只是为了有一个可以安装的程序。
我给我的 Windows 应用程序命名为 CreatingInstaller,当然你可以选择自己的名字。
在解决方案中添加一个新的 Windows 窗体应用程序,并在默认窗体上添加一个文本框和一个按钮,结果如图所示。你可以随意装饰控件属性。
我只是想写几行代码,所以我将按钮的单击事件绑定到显示文本框的文本。
主要目标
到目前为止一切顺利。现在,让我们为同一个 Windows 应用程序创建一个安装程序。右键单击解决方案,然后向解决方案添加一个新项目,如图所示。
添加一个安装项目,选择 **其他项目类型 -> 安装和部署 -> Visual Studio Installer**。
项目将被添加到解决方案中。现在,通过单击项目并选择打开文件系统编辑器选项来打开文件系统编辑器,如图所示。
你将看到“应用程序文件夹”、“用户桌面”和“用户程序菜单”三个选项。
右键单击“应用程序文件夹”并添加项目输出。项目输出指定了我们要为其创建安装程序的项目,如图所示。
在“添加项目输出”窗口中选择 CreatingInstaller(即 Windows 应用程序项目名称),并将其选择为“主要输出”,如图所示,然后单击“确定”。
“主要输出”将被添加,如图所示,类型定义为“输出”。
与此同时,让我们为 Windows 应用程序添加更多功能。让我们读取一个文件,并在单击按钮时将输出显示在消息框中。因此,只需添加一个文本文件。我将其命名为 *Sample.txt*,并将其放在 `bin\debug\Input` 文件夹中,Input 是我创建的用于放置 txt 文件的自定义文件夹。
编写几行代码来读取 Startup 路径下的 txt 文件。在我的例子中是 `bin\debug`,根据项目生成,也可能是 `bin\release`,并指定文件文件夹名和文件名来读取内容。我选择将 txt 文件放在启动路径下,以便我能解释如何在家安装时创建文件和文件夹。现在,我们在安装时也需要这个 Input 文件夹和 *Sample.txt* 文件,以便它们位于已安装应用程序的位置。
对于文件操作,我添加了 `System.IO` 命名空间,尽管这样做是不必要的。
因此,运行应用程序将显示两个消息框,一个接一个地显示文本框的文本和 *Sample.txt* 文件中的文本。
现在,必须在我们的安装项目中实现这个文件夹创建逻辑,以便在安装应用程序时,它具备运行应用程序所需的所有先决条件,例如 Input 文件夹和 *Sample.txt* 文件。
因此,在文件系统编辑器中右键单击“应用程序文件夹”并添加一个文件夹。文件夹将直接创建在“应用程序文件夹”下方,将该文件夹命名为 **Input**。
右键单击该文件夹,选择“属性”,并将“始终创建”属性设置为“True”。这意味着每次我们运行安装程序时,在进行新的发布版本生成后,都会创建该文件夹。
创建快捷方式
你可以装饰你的窗体以添加图标,在安装时也需要这个图标来创建应用程序的快捷方式图标。像下面提到的图一样,为窗体添加一个图标。
是时候添加 *Sample.txt* 文件了。右键单击创建的 Input 文件夹,并添加文件到其中,在之前创建的 Windows 应用程序项目中浏览 *Sample.txt* 文件。
要创建应用程序的快捷方式,请右键单击中间窗口中的“主要输出”,然后选择“为主要输出创建快捷方式”,并将该快捷方式命名为 CreatingInstaller。
右键单击快捷方式,选择其属性,并为其添加一个图标。当应用程序启动时,这个图标将显示在桌面上。下面的图解释了如何添加图标。
剪切在“应用程序文件夹”中创建的快捷方式,并将其粘贴到“用户桌面”文件夹下。
要创建用户程序菜单中的快捷方式,请在用户程序菜单中添加一个新文件夹。该文件夹将出现在程序菜单位置中。创建指向主要输出的新快捷方式,就像我们创建桌面快捷方式时一样。下面的三张图片描述了这个过程。
将文件夹命名为 CreatingInstaller。
右键单击中间窗口创建新快捷方式。
将快捷方式源选择为主要输出。
同样,为快捷方式添加图标,就像为桌面快捷方式所做的那样。
右键单击“应用程序文件夹”以设置应用程序的安装位置属性。
Uninstall
我们始终可以选择从控制面板的“程序和功能”列表中卸载应用程序,但如何创建自己的卸载程序呢?它也位于程序菜单下,这样我们就无需打扰控制面板了。
步骤 1
右键单击“目标计算机上的文件系统”,然后按照下图所示添加“特殊文件夹”->“系统文件夹”。
第二步
右键单击新创建的系统文件夹,并在本地 *System.Windows32* 文件夹中浏览 *msiexec.exe* 文件。该文件负责根据指定的参数安装和卸载应用程序。
将文件属性设置为如图所示。
步骤 3
现在,在“用户程序菜单”下创建一个新快捷方式,并将其源指向 *msiexec*,如图所示。你可以添加更多图标和名称。我将其命名为“卸载”。
步骤 4
按 F4 键选择安装项目。我们看到一个属性列表,我们可以根据我们的安装需求进行自定义,例如产品名称、作者、安装位置。我不会深入讨论所有这些,因为它们很容易理解和设置。
请注意下面属性列表中的产品代码。我们在卸载时需要产品代码作为 *msiexec* 的参数。
步骤 5
右键单击“卸载”快捷方式,并将参数属性设置为如图所示。
/x {product code} /qr /x is for uninstalltion.
你可以在 http://technet.microsoft.com/en-us/library/cc759262(v=ws.10).aspx 上找到参数及其用法的完整详细列表。选择你喜欢的任何一个。
步骤 6
保存所有并重新生成安装项目。
完成!
现在,我们的安装程序已准备好安装我们的 Windows 应用程序。
只需浏览安装项目的调试文件夹位置。我们会发现一个 *msi* 文件和一个 *setup.exe* 文件。你可以运行其中任何一个来启动安装程序。
开始时,我们看到了一个安装向导,其中包含欢迎用户的屏幕,并询问安装位置(而默认位置已设置)。
完成向导后,单击“关闭”按钮。
现在工作完成了,我们可以在桌面上和用户程序菜单中看到应用程序的快捷方式,如图所示。
现在,如果我们导航到安装位置,我们还可以看到创建的 Input 文件夹以及其中存放的 *Sample.txt* 文件。
运行应用程序并查看输出。
单击“卸载”以移除应用程序。向导将启动,如图所示。
Custom Actions
我只是想给一个自定义操作的示例,我们可以在创建安装程序时定义这些操作。
自定义操作是在安装和卸载时包含除默认功能之外的自定义功能的。例如,我的 QC 团队报告了一个 bug,即在运行应用程序的同时在后台卸载应用程序时,应用程序仍然在运行。据他们说,在卸载时应该显示一条消息或关闭。很难向他们解释原因,所以我选择在安装项目中实现他们的愿望。
- 只需为我们之前创建的 Windows 应用程序添加一个安装程序类。当我们打开安装程序类时,我们可以看到为每个自定义操作指定的事件,即安装、卸载、回滚、提交。
我需要编写卸载的代码,所以我写了几行代码来满足需求。
代码包含查找卸载时正在运行的 EXE 名称的逻辑。如果它与我的应用程序 EXE 名称匹配,它将终止进程。这里不再详细介绍。我只是想解释自定义操作的用途。
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Configuration.Install;
using System.Diagnostics;
using System.Linq;
namespace CreatingInstaller
{
[RunInstaller(true)]
public partial class Installer1 : System.Configuration.Install.Installer
{
public override void Install(IDictionary savedState)
{
base.Install(savedState);
//Add custom code here
}
public override void Rollback(IDictionary savedState)
{
base.Rollback(savedState);
//Add custom code here
}
public override void Commit(IDictionary savedState)
{
base.Commit(savedState);
//Add custom code here
}
public override void Uninstall(IDictionary savedState)
{
Process application = null;
foreach (var process in Process.GetProcesses())
{
if (!process.ProcessName.ToLower().Contains("creatinginstaller")) continue;
application = process;
break;
}
if (application != null && application.Responding)
{
application.Kill();
base.Uninstall(savedState);
}
}
}
}
- 选择 **CreatingInstallerSetup** 项目后,单击“自定义操作编辑器”。
- 我们在左侧窗口看到自定义操作编辑器窗格。右键单击它以添加自定义操作,并选择“应用程序文件夹”中的“主要输出”。
- 现在我们看到主要输出被添加为自定义操作。在卸载时,我的自定义操作将被触发,并且在卸载时应用程序将被关闭。
.NET Framework
如果安装机器没有 .NET Framework 怎么办?我们可以指定一个与安装一起提供的包,这样我们的应用程序就不会依赖于客户端机器的 .NET Framework,而是指向我们提供的运行包。
右键单击安装项目,打开属性窗口。
在这里,我们可以指定应用程序安装的先决条件。只需单击“先决条件”按钮,然后在打开的“先决条件”窗口中,选中要遵循的 .NET Framework 应用程序的复选框,然后选择数字 2 处的单选按钮(即“从与我的应用程序相同的位置下载先决条件”)。按“确定”,但保存项目并重新生成它。
现在,当我们浏览安装项目的调试文件夹时,由于我们刚才执行的操作,我们会看到两个额外的文件夹。
现在,必须将整个包提供给客户端机器以安装该应用程序。
现在从 *setup.exe* 重新安装应用程序,并通过快捷方式启动它。
结论
本教程涵盖了创建安装项目的基本步骤。我没有深入解释注册表或许可证协议。还有许多内容需要探索才能理解和掌握这个主题。但是,本文只是为开发者提供一个开始玩转安装和部署的起点。编码愉快!