2013-12-20 80 views
0

感觉这应该有一个简单的解决方案。在2个应用程序之间共享配置

我正在开发一个工具,它将有一些组件 - 它将开始作为一个命令行工具,然后我们将打包在一个wpf应用程序中。该工具用于生成数据库迁移脚本。这些将由源代码控制,并位于每个用户机器的特定位置。

我想将此位置存储为不需要提供给命令行程序的设置,并且可以在UI版本中进行设置。也可能有其他信息在这样的程序之间共享是有用的(一次一次/很少的方式)。

我不想在代码中有配置文件的硬编码路径,因为这不会在程序的不同用户之间移植。

我知道我可以将目录名称传递给命令行应用程序,也可以通过在其计算机上手动设置人员的应用程序配置来完成此操作。我不喜欢前者,因为它是重复的,在命令行输入路径是一种痛苦,我不喜欢后者,因为如果你需要改变它,那么你必须弄清楚程序在做什么,然后在随机文件夹中进行挖掘手动修改文件(这又是非常可怕的!)。

这似乎应该解决问题,它可能是 - 我觉得我可能在某个地方错过了一个把戏。

我对使用本地设置对象并不烦恼 - 在许多方面,我宁愿它只是一个xml文件,因为它使得升级或添加新东西变得更加简单。

想法请!

回答

1
  1. 当程序第一次运行时,您只能向用户索要一次目录。然后,您将在设置中存储提供的值并在之后使用它。当然,你必须提供一个可能性来稍后重写这个值。
  2. 如果我正确理解你,你不想让用户在一些“奇怪的”文件夹中查找配置文件。如果是这样,您可以考虑使用Environment.GetFolderPath以获得路径我的文档,桌面或任何其他知名的目录并保存设置。
  3. 至于设置。它们已经存储为XML。如果你不喜欢这个XML的结构,你可以创建你自己的自定义设置提供者(阅读SettingsProviderAttribute)。您也可以轻松创建自己的解决方案。创建一个具有某些属性的类并将其串行化或反序列化就足够了,例如使用XmlSerialzier
+0

你能否提供更多关于如何使用设置来做到这一点的信息(我认为默认的东西现在应该可以)。我是否需要保持不同项目中的设置同步?这似乎有点讨厌。这些设置通常是透明地存储的,你如何选择他们去的地方?有人提到有Environment.AppData或类似的地方,所以这看起来像是要走的路。 –

+0

您可以使用configSource属性将userSettings部分的内容移动到外部文件中。然后这个外部文件可以在两个应用程序之间共享。但是,这种方法存在局限性,因为这个外部文件不能放在任何地方。它必须与主配置文件位于相同的目录或子目录中。如果你想要更灵活的解决方案,你必须写你自己的设置提供商。 –

0

我推测,您可以使用machine.config来存储全局可见条目。

您可以根据目标的.NET Framework找到它和OS位

  1. 对于.NET 2.0和3.5 - > c:\Windows\Microsoft.NET\Framework\v2.0.50727\CONFIG\
  2. 对于.NET 4。0 - >c:\Windows\Microsoft.NET\Framework\v4.0.30319\Config\

我haven't't应用于应用machine.config中那些不是基于网络。但是,值得一试。

您还可以在MSDN上找到一些示例代码here

注意:如果您处于64位环境中,则有两个machine.config文件。一个用于Framework64,另一个用于框架。确保它在正确的位置,或两者兼而有之。

+0

硬编码的路径似乎不是一个好的方式去 - 我不能假设人们有一个C盘 –

+0

@JonnyLeeds,请仔细阅读问题和建议的答案,然后再评论。我提到的是你可能找到.NET安装和机器配置文件的位置,而不是任何硬编码路径。 – Nair

0

我正在研究的项目最终只是一些命令行工具的集合,其中一些建立在其他项目之上。

这些设置并非设计用于从命令行使用 - 我记录了很多我在this other post中遇到的痛苦。在经历了所有这些事情之后,我终于发现他们不工作交叉组装 - 如果您调用具有另一个程序集设置的程序集,则会得到新设置,而不是其他程序集自行运行时使用的设置。

我最终解决这个问题的方法是手工完成。当它归结到它,它并不难写自己的东西

它的结构是非常相似的库中的一个:

主类看起来是这样的:

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"; 
    } 
} 

的设置本身看起来是这样的:

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; } 
    } 
} 

除此之外,你只需要的东西,写出基础上设置的XML文件,我省略了再加上一些沉闷的我nterfaces +硬编码的公司名称,以求简洁。

相关问题