Updating .config file from an Custom Installer Class Action

后端 未结 5 1265
春和景丽
春和景丽 2021-02-04 20:03

I\'ve tried updating my application\'s .config file during installer (via a .NET Installer Class Action). But, I can\'t seem to get ConfigurationManager to lis

相关标签:
5条回答
  • 2021-02-04 20:26

    Instead of accessing your settings configuration via ConfigurationManager, you should be able to access it via Settings.Default. Settings are more of a Visual Studio feature than a .NET feature...a convenience that makes it easy to visually design your applications configuration rather than manually writing it in appSettings or creating custom configuration sections. However, the configuration schema that is rendered when you use Settings is non-standard, and can be difficult to access manually.

    Visual Studio should have generated a Settings class for you when you built your application, and you should be able to access that class via Properties.Settings.Default. It should have a property for each setting, in your case, the following:

    Properties.Settings.Default.TESTSETTING
    Properties.Settings.Default.VerboseErrorMode
    Properties.Settings.Default.RunOnStartup
    

    You should be able to both read and write these settings. A critical thing to note...anything flagged as a "user" setting will not be written back to the {yourapplication}.exe.config file...it will be written to a User.config file in the users isolated profile storage area. This is under C:\Documents and Settings{username} on XP, and C:\Users{username} on Vista, in the AppData folder. Depending on the OS and users profile, the subfolder under the AppData may change, but its completely unique and keyed to a particular version of the application. Installation of a newer version will result in a completely new set of configuration settings stored under the same keyed folder, but a different version subfolder.

    I hope this helps. :)

    0 讨论(0)
  • 2021-02-04 20:26

    This is what you need: http://social.msdn.microsoft.com/Forums/en-US/csharpgeneral/thread/f89a00eb-9400-48ce-af20-cef78002c14e

    0 讨论(0)
  • 2021-02-04 20:33

    I came across the same problem, after deep investigation, I found out the easiest way to update any part of config files (e.g. app.config), that's by using XPath. We have an application which connects to web service, during the installation, the user enters the URL of the web service and this should be saved in the following app.config file:

            <?xml version="1.0"?>
        <configuration>
          <configSections>
            <sectionGroup name="applicationSettings" type="System.Configuration.ApplicationSettingsGroup, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
              <section name="ApplicationServer.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
            </sectionGroup>
          </configSections>
    
          <applicationSettings>
            <ApplicationServer.Properties.Settings>
              <setting name="ApplicationServer_ApplicationServerUrl" serializeAs="String">
                <value>whatever comes from setup should go here</value>
              </setting>
            </ApplicationServer.Properties.Settings>
          </applicationSettings>
        </configuration>
    

    Here is the code to do this in the installer class:

    public override void Install(System.Collections.IDictionary stateSaver)
        {
            base.Install(stateSaver);
    
            string targetDirectory = Context.Parameters["targetdir"];
            string param1 = Context.Parameters["param1"];
    
            string path = System.IO.Path.Combine(targetDirectory, "app.config");
    
            System.Xml.XmlDocument xDoc = new System.Xml.XmlDocument();
    
            xDoc.Load(path);
    
            System.Xml.XmlNode node = xDoc.SelectSingleNode("/configuration/applicationSettings/Intellisense.ApplicationServer.Properties.Settings/setting[@name='ApplicationServer_ApplicationServerUrl']/value");
            node.InnerText = (param1.EndsWith("/") ? param1 : param1 + "/");
    
            xDoc.Save(path); // saves the web.config file  
        }
    

    Basically, since the config file is a XML based document, I am using XPath expression to locate specific node and change its value.

    0 讨论(0)
  • 2021-02-04 20:40

    One thing to try is moving it from install to Commit to ensure that the file has been written first before trying to access it. Alternatively you could use the custom action to write your own file and just alter your config file to point at the alternative xml file.

    I worked on a Sharepoint product install where I dug into all of this and I will admit it is very tedious to get working correctly. I was creating config and batch files on the fly based on install parameters.

    0 讨论(0)
  • 2021-02-04 20:40

    You can access these settings using the System.Configuration namespace but, its not as simple as I would like and in retrospect using System.Xml.Linq is far simpler. Anyway, here is how I got it to work.

    The important concept is, the applicationSettings section is not AppSettings, its a seperate section supported by the ClientSettingsSection type.

    //Open the application level config file
    ExeConfigurationFileMap exeMap = new ExeConfigurationFileMap();
    exeMap.ExeConfigFilename = String.Format("{0}.config", 
        Context.Parameters["assemblypath"]);
    Configuration config = ConfigurationManager.OpenMappedExeConfiguration(exeMap,
        ConfigurationUserLevel.None);
    
    //Get the settings section
    ClientSettingsSection settingsSection =
        config.GetSectionGroup("applicationSettings").Sections
             .OfType<ClientSettingsSection>().Single();
    
    //Update "TheSetting"
    //I couldn't get the changes to persist unless
    //I removed then readded the element.
    
    SettingElement oldElement = settingsSection.Get("TheSetting");
    settingsSection.Settings.Remove(oldElement);
    
    SettingElement newElement = new SettingElement("TheSetting", 
        SettingSerializeAs.String);
    newElement.Value = new SettingValueElement();
    newElement.Value.ValueXml = oldElement.Value.ValueXml.CloneNode(true);
    newElement.Value.ValueXml.InnerText = "Some New Value";
    settingsSection.Add(newElement);
    
    //Save the changes
    config.Save(ConfigurationSaveMode.Full);
    

    So, as you can see, simple. :-S

    0 讨论(0)
提交回复
热议问题