【问题标题】:Best Practice for storing settings for a .NET Windows Service: Service Property Settings, Serialization,存储 .NET Windows 服务设置的最佳实践:服务属性设置、序列化、
【发布时间】:2010-08-05 13:21:46
【问题描述】:

我正在开发一个 .NET Windows 服务,我试图在其中存储将在服务启动和运行时使用的设置。我搜索了关于 SO 的帖子,发现使用项目属性中的设置非常适合与控制台和 winforms 应用程序一起使用。但是,Google 和 SO 在涉及使用 Windows 服务存储这些设置时保持沉默。

有谁知道在 .NET 服务中使用这些设置是否合适?如果不是,序列化是我的下一个最佳选择吗?有没有人对服务中的设置进行过实际使用,并发现最好使用特定的方法?

【问题讨论】:

    标签: c# vb.net visual-studio windows-services configuration-files


    【解决方案1】:

    我在使用 Settings.settings 时遇到了问题。例如,如果您需要在运行时进行更改,可能会出现设置被最初存储在 settings.settings 文件中的设置覆盖的问题,而不是显示的应该存储的设置根据 app/web.config。因此,我在属性中将所有 Web 服务代理设置设为“静态”,并通过辅助方法从 app/web.config 手动拉取它们并以编程方式设置它们。这样可以避免任何问题。

    我们遇到的问题的一个示例:我将我的开发机器指向测试服务器上的 Web 服务,以测试使用该 Web 服务的代码。当代码移动到我们的测试服务器时,没有出现任何问题——因为测试服务器仍然指向同一个测试服务器上的同一个 Web 服务。然而,当我们将应用程序移动到生产服务器并重新配置 web.config 以指向生产服务器时,我们开始得到令人讨厌的结果。尽管我们已经重新配置应用程序以指向生产服务器的 Web 服务实现,但它仍然连接到测试服务器上的 Web 服务,这需要付出相当多的努力。直到我们更改了我的开发机器上的 settings.settings 并重新编译了它工作的应用程序。除此之外,我们还注意到,如果连接到生产 Web 服务时出现 DNS 问题,而不是失败,它会退回到我们在应用程序中创建 Web 服务代理时在 settings.settings 中指定的原始设置- 代理生成器实际上对它们进行了硬编码。因此,当出现网络中断时,不是很容易诊断出连接故障,而是简单地退回到测试服务器,我们开始遇到难以理解的数据问题。我不确定这是一个已知问题还是已解决,但这当然是您应该注意的问题。

    因此,从那时起,我一直将服务属性设置为静态,并使用辅助方法直接从 web.config 读取正确的设置并以编程方式编写它们,因为这似乎可以规避问题。

    看起来我的问题与您的问题无关,因为我使用的 Web 服务与 Windows 服务无关,但是,您需要能够在运行时更改设置的任何环境无需重新编译可能会受到此问题的影响,因此您应该注意,如果您在开发/测试/生产环境中运行,或者实际上在任何需要在运行时重新配置您的应用程序的环境中运行(即无需重新编译) 使用 settings.settings 时可能会得到不可预知的结果。小心。

    【讨论】:

    • 感谢您非常详细的回答。我会投赞成票,但我还没有足够的声望点。感谢您花时间回答这个问题。
    • 我不得不承认我根本没有遇到过这些问题,而且我们使用了很多 Windows 服务,其中应用程序设置是从 app.config 文件中读取的——包括 Web 服务 URL。你认为这个问题是 windows services v win forms 应用程序特有的,还是只是一般的 app.config 错误/问题?
    • @barrylloyd - 老实说,我没有对框架的哪些区域进行大量调查,因为它是一个关键任务应用程序 [即把它修好并继续前进]。根据我所做的调查,似乎问题可能与 Web 服务代理与 settings.settings 的交互有关,而不是正确连接到 web.config 以查找其设置。可能只影响框架的这个区域,可能影响其他区域,我不确定。
    • @barrylloyd @benAlabaster 我认为问题在于您如何访问设置。我认为是这样的:如果您在 VB.Net 中使用 My.Settings 访问它们,它将从 .config 文件中读取设置,但如果您使用的是 C# 中看起来相同的设置 (Settings.Default),然后您将阅读编译的默认设置。为避免在 C# 中出现这种情况,您必须创建我认为的设置对象的实例。当然,记住在需要时重新加载和保存设置也很重要(我通常在 OnStart 和 OnStop 中这样做)。
    • 对于 necro 帖子感到抱歉,但我只想指出,为了覆盖默认设置,您必须在“主机”程序集中执行此操作。基本上无论您的 Program Main() 是什么,或者 global.asax 或 Startup.cs。您需要将
      从您的类库复制到您的主 app.config,然后您可以覆盖 部分。希望能有所帮助/有意义。
    【解决方案2】:

    我通常使用注册表来存储我在服务中需要的信息,即端口等。

    string lsbkey = @"Software\mycompany\adas";
    
    RegistryKey adaskey = Registry.LocalMachine.OpenSubKey(lsbkey, false);
    
    try
    {
        object regip = adaskey.GetValue("IP");
        object regport = adaskey.GetValue("PORT");
        localip = regip.ToString();
        localport = int.Parse(regport.ToString());
    }
    catch (NullReferenceException ne)
    {
        localip = null;
        localport = 0;
        writelog(@"Aborting Service, IP or PORT doesn't exist in \local machine\software\mycompany\adas : "+ne.Message);
        status = 0;
    
    }
    

    【讨论】:

      【解决方案3】:

      我使用Settings.settings 东西来存储我的服务的配置,我没有遇到任何问题。通常,更改的用户设置将存储在它通常不起眼的位置,如果您想手动编辑它们,您必须四处寻找。

      【讨论】:

        【解决方案4】:

        我看不出有任何理由不使用项目属性中的设置,就像使用 winForms 应用程序一样。我们这样做了,而且效果很好。

        【讨论】:

        • 在属性中使用设置的问题在于它取决于登录的用户,因为设置存储在用户配置文件中。如果多个管理员正在使用该服务,那么设置将会改变。
        猜你喜欢
        • 2012-06-26
        • 2010-09-19
        • 1970-01-01
        • 1970-01-01
        • 2013-05-08
        • 2011-11-20
        • 1970-01-01
        • 2012-05-10
        相关资源
        最近更新 更多