首页 > 解决方案 > 作为使用免费版 Visual Studio 的 Windows Installer 设置的一部分,如何更改 VB .net 应用程序的设置?

问题描述

<app>.exe.config作为设置操作的一部分,我想更改我的应用程序文件的某些部分。例如,这可能是应用程序的数据库连接字符串。

如何做到这一点,受以下限制:

  1. 将最少的额外组件安装到 Visual Studio。(基本上只是安装程序模板)
  2. 最少,最好没有外部工具。
  3. 作为一套完整的指令。
  4. 提供一个简单的工作示例。

到目前为止,我在互联网上找到了一些描述如何做到这一点的资源,但没有人能正确理解。每个人似乎都忘记或假设已经完成了一些步骤,因此盲目地遵循任何所谓的“教程”不会让你成为一个有效的安装程序。

标签: .netvb.netwindows-installercustom-action

解决方案


经过大量的实验和逐步将各种在线资源拼凑在一起,我找到了一个完整的工作解决方案。由于要获得最终结果有很多复杂的步骤:为了有兴趣的人的利益,我在这里分享它。

在整个解释中,<app>[app]将用于表示应用程序的名称。在使用前者可能会造成混淆的情况下,我将使用后者的括号。

下载先决条件

首先,确保您只有一个正在运行的 Visual Studio 实例。

接下来,您将要打开Tools > Extensions and Updates并下载然后安装Microsoft Visual Studio 20xx Installer Projects

下载完成后,安装并重新启动 Visual Studio。

创建基本安装程序

接下来,通过添加类型为Visual Studio Installer > Setup Project的项目来创建新的安装程序项目。将您想要在安装程序中输出的项目添加到安装程序项目中。这会在构建时创建一个预配置的简单 msi 安装程序文件。

接下来,在解决方案资源管理器中右键单击您的解决方案,然后转到Project Dependencies。确保您的安装程序项目依赖于您安装的项目。

然后在解决方案资源管理器中右键单击您的安装程序项目并从那里打开配置管理器(或从您的解决方案或标题栏菜单访问它),然后将安装程序项目启用为Build

右键单击安装程序项目并转到查看文件系统。打开左侧面板上的应用程序文件夹,然后右键单击该文件夹以添加 > 项目输出...选择应用程序的主输出。您还可以在此处添加作为构建过程的一部分生成的任何辅助文件。

在构建解决方案之后,您现在有了一个工作的、“可测试的” 1简单设置。

添加自定义变量

在此示例中,我们将使用自定义操作将简单的文本输入传递给新应用程序的<app>.exe.config文件。

我们的自定义变量将是应用程序 SQL 服务器的路径。我在这里假设这个变量在<app>.exe.config文件中被命名为“Server”。

右键单击自定义安装程序并转到View > Custom Actions。通过右键单击该文件夹然后选择添加来添加自定义安装操作。这会打开一个相当奇怪的窗口,要求您“选择项目中的项目”。将“查找”文件夹更改为指向目标机器上的文件系统 > 应用程序文件夹 > [app]。单击添加输出...并添加要修改其设置的主应用程序的输出。2左侧窗口现在应该包含一个项目,表示<app> 的主要输出(活动)

选择此项并CustomActionData在“属性”窗口中更改。我们将此值更改为完全/SqlPath=[SQLPATH] /TargetDir="[TARGETDIR]\"。该数据的编码如下:3

Start with a single forward slash "/" 
Encode the variables as [name-in-installer-class]=[name-in-installer-project]
If your name in the installer project contains spaces you must surround it with double quotes
Separate each variable with a space and forward-slash or " /"
TARGETDIR is a special variable and is encoded as [name-in-installer-class]="[TARGETDIR]\"

导航到安装程序项目中的查看 > 用户界面。在Install > Start添加一个新的 type 形式Textboxes (A)。在属性窗口中,禁用底部的 3 个文本框,然后设置这些变量:

  1. BannerText, 到窗口标题(例如“数据库”)
  2. BodyText,此设置步骤的可选额外描述
  3. Edit1Label, "SQL 服务器路径"
  4. Edit1Property, 正是“SQLPATH”
  5. Edit1ValueSQL 服务器路径的默认值。

接下来,将安装程序类添加到我们要修改其设置的项目中。添加 > 新项目,然后在模板中搜索“安装程序类”。自定义如下。(将代码中的“APPNAME”替换为可执行文件的名称):

Imports System.ComponentModel
Imports System.Configuration

Public Class clsInstaller
    Inherits System.Configuration.Install.Installer

    Public Sub New()
        MyBase.New()

        'This call is required by the Component Designer.
        InitializeComponent()

        'Add initialization code after the call to InitializeComponent

    End Sub

    Public Overrides Sub Install(ByVal stateServer As System.Collections.IDictionary)
        MyBase.Install(stateServer)
        ' Change the Application settings' 'database connection' setting. 
        ' Note: targetDirectory contains an extra '\' at the end. 
        Dim targetDirectory As String = Context.Parameters("TargetDir")
        Dim str As String = ""
        'For some reason custom fields are sent escaped to the installer class. 
        'This undoes the escaping of the directory slashes.
        Dim sqlServerPath As String = Context.Parameters("SqlPath").Replace("\\", "\")
        Dim executablePath As String = String.Format("{0}APPNAME.exe",
            targetDirectory.Substring(0, targetDirectory.Length - 1))
        Dim config As Configuration = 
           ConfigurationManager.OpenExeConfiguration(executablePath)
        If config Is Nothing Then
            MessageBox.Show("Failed to load configuration file", "Error", 
                MessageBoxButtons.OK, MessageBoxIcon.Error)
        End If
        Dim sectionGroup As ConfigurationSectionGroup = 
           config.GetSectionGroup("applicationSettings")
        Dim configSection As ConfigurationSection = 
           sectionGroup.Sections("APPNAME.My.MySettings")
        Dim settingsSection As ClientSettingsSection = 
           CType(configSection, ClientSettingsSection)
        Dim serverSetting As SettingElement = 
           settingsSection.Settings.Get("Server")
        serverSetting.Value.ValueXml.InnerText = sqlServerPath
        configSection.SectionInformation.ForceSave = True
        config.Save()
    End Sub
End Class

构建解决方案,安装程序现在应该修改应用程序的设置文件!

笔记

1:从某种意义上说,您可以手动运行它。实际上调试需要从设置中实例化它。看到这个问题

2: It's also possible to add a separate project here to create a separate dll whose purpose is to provide the custom code entry point. This has better performance characteristics but is avoided in this example because of increased complexity (you would have to get one program to modify another program's settings file).

3:For more information about this encoding consult the article about CustomActionData Property on MSDN.

4: The ConfigurationManager section group and section names are case sensitive, so make sure they exactly match as they are in the actual setting XML file.


推荐阅读