65.9K
CodeProject 正在变化。 阅读更多。
Home

一个安装和部署项目,该项目将参数传递给配置文件

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.81/5 (58投票s)

2006年1月20日

8分钟阅读

viewsIcon

395451

downloadIcon

5823

一篇关于如何使用 .NET 中的设置和部署项目并根据自身需求进行调整的文章。

引言

我是一名还在挣扎的年轻软件开发者,我经常会在网上搜索各种问题的解决方案,而 CodeProject 几乎总能满足我的需求。这次我遇到了另一个问题:我想创建一个设置和部署项目,在安装过程中从用户那里获取参数并将其传递到我应用程序的配置文件中。花了些时间,但我设法找到了一种方法来实现它。

在本文中,我将演示如何创建一个 Windows 设置项目,该项目在安装过程中接收用户的字符串输入,并将其写入应用程序的配置文件中。

背景

简而言之,整个过程如下:

  • 我们创建一个要安装的项目。
  • 我们创建一个 Setup And Deployment 项目,该项目将在目标计算机上安装前一个项目。
  • 在设置项目的“文件系统”窗口中,我们添加应用程序的主输出,并执行所有常规操作。
  • 我们在设置项目的“用户界面”窗口中添加一个新的对话框窗口,该窗口包含一个文本框,用户将在其中输入他们的字符串。
  • 我们添加一个派生自 `Installer` 类的新类,并重写我们想要在安装过程中使用的那些方法(`Install`、`Commit`、`Rollback` 和 `Uninstall`)。
  • 通过在“自定义操作”窗口中将我们的主输出添加到“安装自定义操作”中,我们将新的派生自 `Installer` 的类“连接”到设置项目。
  • 我们公开新添加的对话框窗口中的文本框,以便代码可以访问它。
  • 最后,我们编写在安装过程中要执行的代码(在本例中,代码从新添加的对话框中读取字符串,并更新目标计算机上的配置文件)。

使用代码

开始动手吧……

首先,我创建了一个简单的 Windows 应用程序,它从配置文件中获取一个路径,并将窗体的背景图像设置为该路径。

app.config 文件如下所示:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
       <appSettings>
        <add key="FilePath" value="..\..\Images\penguin.png"/>
    </appSettings>
</configuration>

窗体的构造函数获取该字符串,并将 `BackgroundImage` 属性设置为给定的字符串,该字符串实际上代表了图像文件。

构造函数如下所示

public Form1()
{
    //
    // Required for Windows Form Designer support
    //
    InitializeComponent();

    // Get the path for the background Image from app.Config
    string filePath = 
      ConfigurationSettings.AppSettings["FilePath"];

    // Set the BackgroundImage property
    Image backImage = Image.FromFile(filePath);
    this.BackgroundImage = backImage.GetThumbnailImage(
    this.Width, 
    this.Height, 
    null, 
    IntPtr.Zero);
    this.Refresh();
}

别忘了添加对 `System.Configuration` 命名空间的引用,以便访问 `ConfigurationSettings.AppSettings`。

现在,我想为我的桌面应用程序创建一个设置和部署项目。为此,我们需要向我们的解决方案添加一个新项目,并选择设置和部署项目选项,如下图所示,并在模板选项中选择“Setup Project”选项。

图 1:添加设置和部署项目。

添加项目后,我们可以看到“文件系统”窗口。

图 2:文件系统窗口。

此窗口有三个默认文件夹:

  • 应用程序文件夹 - 显示文件在目标计算机上的安装结构。在这里,我通过右键单击“应用程序文件夹”并选择“添加”,然后选择“项目输出”来放置应用程序的主输出,如下图所示。

    图 3:将主输出添加到应用程序文件夹。

  • 用户桌面 - 此文件夹中的项目将安装到用户桌面。我通过右键单击(已添加到“应用程序文件夹”的)主输出并选择“创建快捷方式”选项,将应用程序快捷方式添加到此文件夹。然后将新创建的快捷方式移动到“用户桌面”文件夹。
  • 用户程序菜单 - 此文件夹中的项目将安装到“所有程序”菜单项下的“开始”菜单。

通过右键单击根目录(“目标计算机上的文件系统”),可以在“文件系统”窗口的树中添加更多文件夹,其中每个文件夹会将放置其中的项目安装到目标计算机上的类似位置。

到目前为止,我所做的只是将我的应用程序安装到目标计算机上并创建其桌面快捷方式。

当我们运行安装向导时,我们只能看到三个屏幕:欢迎屏幕、安装文件夹屏幕(在此屏幕中,我们指定安装应用程序的位置,安装向导将在此位置安装我们在“文件系统”窗口的“应用程序文件夹”节点中放置的所有项目)和确认屏幕,这是安装完成前的最后一个屏幕。

现在,让我们来玩转安装向导并添加更多屏幕。首先,我们需要在解决方案资源管理器中右键单击设置项目,然后在“视图”选项中选择“用户界面”(如下图所示)。在此屏幕中,我们看到一个指定安装向导屏幕顺序的树。在“安装”节点下,您可以看到三个默认屏幕。我通过右键单击“安装”节点并选择“添加对话框”选项(图 5)添加了一个带有文本框的屏幕,供用户输入字符串。您会看到许多可以添加的对话框。我选择了 TextBoxes (A) 对话框。

图 4:查看“用户界面”窗口以向安装向导添加更多对话框。

图 5:向“用户界面”窗口添加对话框。

在我添加到向导的 TextBoxes 对话框中,默认有四个文本框,但我只需要一个,所以我只需在属性窗口中将其他三个文本框的 `Visible` 属性更改为 `false`。在属性窗口中,您还可以调整对话框横幅和正文的文本。

添加对话框后,我们需要在安装过程中执行某种操作,该操作将获取新对话框中文本框中的字符串,并更新配置文件。

现在,我们编写一个将在安装过程中调用的方法。为此,我们需要创建一个派生自 `Installer` 类的类,并添加 `[RunInstaller(true)]` 属性。新类可以重写四个主要方法:`Install`、`Uninstall`、`Commit` 和 `Rollback`。

[RunInstaller(true)]
public class InstallHelper : Installer
{
    *
    *
    *

在此类中,我重写了 `Install` 方法,在该方法中我将获取新文本框中的文本,并更新配置文件。

但是,为了让安装向导调用我们的方法,我们首先需要添加一个自定义操作。通过在解决方案资源管理器窗口中右键单击设置项目并单击“视图”->“自定义操作”,我们可以看到“自定义操作”窗口,其中包含一个具有四个节点的树:安装、提交、回滚和卸载。

我现在需要做的是将安装向导“连接”到我的 `Install` 方法,所以我通过右键单击“安装”节点并单击“添加自定义操作”来添加一个新的自定义操作。

图 6:自定义操作窗口。

完成此操作后,会弹出一个窗口,我在其中选择我的应用程序的主输出(在我的应用程序中,我有 `InstallerHelper` 类)。

图 7:添加自定义操作。

请注意,对于我们可以重写的每个方法(在派生自 `Installer` 的类中),我们在自定义操作窗口中都有一个节点。

现在,当安装向导运行时,它将执行我重写的 `Install` 方法。

现在我们需要做的是:

  1. 公开新对话框中 `TextBox` 的 `Text` 属性,以便代码可以访问其值。
  2. 在 `Install` 方法中编写更新配置文件的代码。

要公开 `Text` 属性,我们转到新添加的自定义操作的属性窗口。在这里,我们可以看到一个名为 `CustomActionData` 的属性,我在这里以 `/<key>=[<property name>]` 的格式声明我的 `Text` 属性。我的特定声明是“`/PathValue=[EDITA1]`”,因为 `PathValue` 是我给定的名称,我将在稍后在代码中获取该属性值,而 `TextBox` 的名称是“`EDITA1`”。

图 8:更新 `CustomActionData` 属性。

请注意,您可以添加任意数量的声明。

现在,我们终于可以编写一些代码了。

要从代码中读取 `TextBox` 的值,我们只需在我们重写的 `Install` 方法中,从 `Context.Parameters[key]` 读取值,其中“`key`”实际上是我们声明属性时写入的键(当我们公开文本框时)。在我的例子中,键当然是“`PathValue`”。

请注意,`Context.Parameters` 属性的默认值不包含我们新文本框的 `Text` 属性。我们必须在自定义操作属性窗口中公开它。

另一个重要事实是,安装应用程序后,配置文件在目标计算机上以可执行文件的名称加上 `.config` 后缀的形式存在。例如,如果安装后的可执行文件是“`MyApp.exe`”,则在同一目录下,您会找到配置文件“`MyApp.exe.config`”(当然,前提是该应用程序有一个配置文件)。

“`Context.Parameters`”属性中的另一个重要值是将被安装到目标计算机上的可执行文件的路径。由于我们知道配置文件具有完全相同的路径加上 `.config` 后缀,所以我们拥有配置文件的路径。

// Get the path to the executable file that is being installed on 
// the target computer
string assemblypath = Context.Parameters["assemblypath"];
string appConfigPath = assemblypath + ".config";

所有剩余的工作是使用 `XmlDocument` 类来更新我们已获得路径的配置文件。您可以在附件的文件中查看我的代码。

希望这对您有所帮助,就像您一直帮助我一样。

关注点

非常重要:请注意,用户无法在文本框中输入带空格的字符串。出于我未知的原因,每当我输入带空格的字符串时,安装就会失败。

© . All rights reserved.