简体   繁体   中英

Sharing configuration between 2 applications

It feels like this should have a simple solution.

Im developing a tool which is going to have a couple of components - its going to start as a command line tool that we're then going to wrap in a wpf app. The tool is for producing database migration scripts. These are going to be source controlled and sit in a particular place on each user's machine.

I would like to store this location as a setting that doesnt need providing to the command line program and that can be set in the UI version. There may also be other information it would be useful to share between the programs like this (in a set once/rarely way).

I dont want to have a hard-coded path to a config file in the code as that isn't going to be portable between different users of the program.

I know I could just pass the directory name to the command-line app and could also do it by having an app config that people manually set once on their machine. I dont like the former because it's repetitive and typing paths on the command line is a pain and I dont like the latter because if you need to change it then you have to figure out what the program is doing and then go digging around in random folders to modify the file by hand (which again is quite horrible!).

It seems like this should be solved problem and it probably is - I feel like I'm probably missing a trick somewhere.

I'm not bothered about using native Settings objects - in many ways I would prefer it to just be an xml file somewhere as that keeps things nice and simple for upgrading or adding new things to.

Ideas please!

  1. You could ask a user for a directory only once, when the program is run for the first time. Then you will store provided value in settings and use it afterwards. Of course you have to provide a possibility to override this value later.
  2. If I understand you correctly, you don't want to make user to look for configuration file in some "strange" folders. If so, you can consider using Environment.GetFolderPath in order to get path to MyDocuments , Desktop or any other well know directory and save settings there.
  3. As to the settings. They are already stored as XML. If you don't like the structure of this XML, you can create your own custom settings provider (read about SettingsProviderAttribute ). You can also easily create your own solution. It is enough to create a class with some properties and serialize/deserialize it for example with XmlSerialzier .

I presume, you can use machine.config to store globally visible entries.

You can locate it on based on target .net framework and OS bit

  1. For .NET 2.0 and 3.5 -> c:\\Windows\\Microsoft.NET\\Framework\\v2.0.50727\\CONFIG\\
  2. For .NET 4.0 -> c:\\Windows\\Microsoft.NET\\Framework\\v4.0.30319\\Config\\

I haven't't used machine.config in application those are not web based. However, it worth a try.

You can also find some sample code here at MSDN.

Note: There are two machine.config files if you are in a 64-bit environment. One for Framework64 and one for Framework. Make sure it is in the right one, or both.

The project I was working on has ended up just being a collection of command line tools some of which build on top of other ones.

The settings really aren't designed to be used from the command line - I've documented a lot of the pain I ran into in this other post . After going through all this stuff I finally discovered they dont work cross-assembly - if you call an assembly that has settings from another assembly you will get new settings rather than the settings that the other assembly would use if it was run on it's own.

The way I solved this in the end was to just do it by hand. When it comes down to it, its not hard to write something yourself

The architecture of it is fairly similar to the library one:

The main class looks like this:

public class ProgramSettings
{
    private readonly string _path;
    private readonly List<Setting> _settings;
    private readonly SettingProvider _settingProvider;
    private readonly ConsoleWriter _writer;

    public ProgramSettings(string programName, SettingProviderFactory settingProviderFactory, ConsoleWriter writer)
    {
        _writer = writer;
        var appData = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
        var folder = Path.Combine(appData, companyName, programName);
        _path = Path.Combine(folder, "settings.xml");
        _settings = new List<Setting>();

        if (!Directory.Exists(folder))
            Directory.CreateDirectory(folder);

        _settingProvider = settingProviderFactory.GetProvider(_path, _settings);
    }

    public Setting Add(string name, string description)
    {
        var setting = new Setting(name, description);
        _settings.Add(setting);
        return setting;
    }

    public string Load()
    {
        _settingProvider.Load();
        _writer.WriteLine("using config at " + _path);

        if (_settings.All(s => s.IsSet))
            return null;

        _settingProvider.Save();

        var description = string.Join("\n", _settings.Where(s => !s.IsSet).Select(s => s.Description));
        return description + "\n need setting in config";
    }
}

A setting itself looks like this:

public class Setting
{
    private readonly string _description;
    public string Name { get; private set; }

    public Setting(string name, string description)
    {
        Name = name;
        _description = description;
    }

    public string Value { get; set; }

    public string Description
    {
        get { return string.Format("{0}: {1}", Name, _description); }
    }

    public bool IsSet
    {
        get { return Value != null; }
    }
}

Apart from that you just need something that writes out an xml file based on the settings I've omitted that plus a few unexciting interfaces + hardcoded company names for the sake of brevity.

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