我一直在用 c# 制作一个命令行工具,我们最终使用了一些参数的配置,这些参数只需要设置一次。我被告知只设置一个空白配置,而不是为这些提供 UI,如果未设置这些值,则提供一条消息来说明配置的位置并进行设置。
事实证明这非常困难!
我需要能够做的事情如下:
- 获取配置路径
- 为相关属性保存带有存根的空白配置
该工具是使用 CC.net 发布的,并使用 wix 创建了一个 msi。不幸的是,这是相关的!
我一直在用 c# 制作一个命令行工具,我们最终使用了一些参数的配置,这些参数只需要设置一次。我被告知只设置一个空白配置,而不是为这些提供 UI,如果未设置这些值,则提供一条消息来说明配置的位置并进行设置。
事实证明这非常困难!
我需要能够做的事情如下:
该工具是使用 CC.net 发布的,并使用 wix 创建了一个 msi。不幸的是,这是相关的!
获取配置路径
这一点结果很容易:
你只需使用这样的东西:
public string FileLocation
{
get { return Configuration.FilePath; }
}
private static Configuration Configuration
{
get { return OpenConfig(ConfigurationUserLevel.PerUserRoamingAndLocal); }
}
private static Configuration OpenConfig(ConfigurationUserLevel userLevel)
{
return ConfigurationManager.OpenExeConfiguration(userLevel);
}
传入的枚举还有两个其他值: None 似乎指向 app.config 的位置,而 PerUserRoaming 似乎总是指向不存在的某个地方。我无法找到有关何时适合使用的更多详细信息,但在我的情况下似乎不适合。
正如上面刚刚提到的,关于这个调用的一个令人困惑的事情是,如果一个文件被保存/存在,它将返回文件的路径。这意味着该文件通常不存在!ConfigurationManager 和 Settings(从 ApplicationSettingsBase 派生的自动生成的类)之间不明确的关系让我非常痛苦!
保存空白配置
一些绊脚石如下:
如果你添加一个 settings.Settings 类,这也会添加一个 app.config。除非您将其与已安装的程序一起发布,否则您将看到程序的已安装版本和开发版本之间的不同行为 - 一个将使用 app.config 中的值创建设置文件,而另一个则不会。对我来说最简单的解决方案是完全删除 app.config。
我试图在 Configuration 上使用 save 方法,它允许您指定保存所有属性(无论值是默认值),并允许您指定保存,即使配置尚未修改。但是,在设置了两个标志的情况下调用此方法不会做任何事情 - 您在设计器中创建的设置似乎在设置之前不是真实的 - Configuration 和 ConfigurationManager 是较旧的做事方式,而 ApplicationSettingsBase 可能使用一个或两个其中他们没有很好地整合。
更令人困惑的是,如果您查询设置,那么它们将具有值(对于字符串,它们将具有“”)。但是,如果您保存设置,则这些设置不会保存到文件中指定的位置!事实上,根本不会创建任何文件!虽然如果您有一个 app.config,但如果您使用上面的强制保存方法,则会创建一个文件,因为默认值在 app.config 中指定!
解决方案似乎是检查每个属性中的默认值,然后设置默认值。这看起来应该是一个空操作,但 getter 不遵循“如果我没有设置,我将在查询时创建它”的逻辑,而是假装一个存在具有默认值的设置。设置任何值似乎实际上是在创建设置。
var somethingUnSet = _settings.Something == "";
if (somethingUnset)
_settings.Something = "";
if(somethingUnset|| somethingElseUnset)
{
_settings.Save();
ExitWithError("config needs setting up at " + _settings.FileLocation);
return;
}
最后,这给了我想要的结果 - 一个文件保存在配置管理器指定的位置,其中包含需要填写的空属性。认为 UI 会更快!
我使用包装的 Settings 对象来促进更改测试中的值,而无需处理单例。这也有一个很好的副作用,您可以添加额外的代码(例如文件位置),而不必担心添加更多设置时代码生成会覆盖内容。
只需在第一次启动时将 .config 文件中的所有项目设置为空,如下所示:
ConfigurationManager.appSettings["item1"] = "";
并检查值。
但是你为什么不检查参数是否设置,如果没有抛出错误,我认为你不需要清除配置文件来检查它是否第一次启动