简体   繁体   中英

How to alter a VB .net application's settings as part of a Windows Installer setup using free edition Visual Studio?

I want to alter some part of my application's <app>.exe.config file as part of the setup operation. For example, this could be the application's database connection string.

How do I do this, subject to the following constraints:

  1. With a minimum of extra components installed to Visual Studio. (Essentially just the installer templates)
  2. With a minimum, preferrably no external tooling.
  3. As a complete set of instructions.
  4. Provide a simple working example.

So far I have found several resources on the internet describing how to do this, but nobody gets it right. Everyone seems to forget or assume some steps are done, so blindly following any of the purported 'tutorials' does not get you a working installer.

After much experimentation and piece-by-piece cobbling various online resources together, I have found a complete working solution. As there are so many convoluted steps to get the final result: For the benefit of those interested, I'm sharing it here.

Throughout this explanation, <app> or [app] will be used to denote the application's name. I will use the latter brackets in those cases where using the former may create confusion.

Download Prerequisites

First, make sure you only have one running instance of Visual Studio.

Next, you're going to want to open Tools > Extensions and Updates and download then install Microsoft Visual Studio 20xx Installer Projects .

After the download completes, install it and restart Visual Studio.

Creating a basic Installer

Next, create a new Installer Project by adding a project of type Visual Studio Installer > Setup Project . Add the project(s) whose outputs you want in the installer to the installer project. This creates a pre-configured simple msi installer file on build.

Next, right click your Solution in the Solution Explorer and go to Project Dependencies . Make sure you get your installer project to depend on your installed project.

Then right click your Installer Project in the Solution Explorer and open the Configuration Manager from there (or access it from your solution or the title bar menu), then enable the installer project to Build .

Right click on the Installer Project and go to View file system . Open the Application Folder on the left-hand panel then right click the folder to Add > Project Output... Select the Primary Output of your application. You can also add any auxillary files that are produced as part of the build process here.

You now have a working, 'Testable' 1 simple setup after Building the solution.

Adding a custom variable

In this example we will use a custom action to pass a simple text input to the new application's <app>.exe.config file.

Our custom variable will be the path to the application's SQL server. I assume here that this variable is named "Server" in the <app>.exe.config file.

Right click the custom installer and go to View > Custom Actions . Add a custom Install action by right clicking that Folder then selecting Add . This opens a rather strange window that asks you to 'Select item in Project'. Change the 'Look In' folder to point towards File System on Target Machine > Application Folder > [app] . Click Add Output... and add the output of the main application whose settings you want to modify. 2 The left hand window should now contain an item denoting Primary output from <app> (Active)

Select this and change the CustomActionData in the Properties window. We change this value to be exactly /SqlPath=[SQLPATH] /TargetDir="[TARGETDIR]\\" . The encoding for this data works as follows: 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]\"

Navigate to View > User Interface in the Installer project. Under Install > Start add a new form of type Textboxes (A) . In the properties window, disable the bottom 3 textboxes, then set these variables:

  1. BannerText , to the window title (eg "Database")
  2. BodyText , an optional extra description of this setup step
  3. Edit1Label , "SQL server path"
  4. Edit1Property , exactly "SQLPATH"
  5. Edit1Value The default value for the SQL server path.

Next, add an installer class to the project we want to modify settings of. Add > New Item then search the templates for 'Installer Class'. Customize it as follows. (Replace 'APPNAME' in the code with the name of the executable):

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

Build the solution, and the installer should now modify the application's settings file!

Notes

1 : In the sense that you can manually run it. Actually debugging requires instantiating it from the setup. See this question .

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM