【问题标题】:Using a Windows application to modify settings used by a Windows service使用 Windows 应用程序修改 Windows 服务使用的设置
【发布时间】:2013-02-08 15:35:42
【问题描述】:

我目前正在使用 InstallSheild LE 安装一个 Windows 服务(作为 LocalSystem 运行)。该服务旨在从本地数据库文件中读取一些数据,将其打包,并以设定的时间间隔将其发布到外部服务器。我想从设置文件中读取数据库位置、服务器 url 等硬编码。我可以使用 App.config 轻松地做到这一点,但从我的研究中我了解到修改 App.config(或 Program Files 中的任何文件)在安装后是困难/不可能的。

我的问题是拥有一个应用程序的最佳方式是什么,我可以运行该应用程序来修改服务的必要设置,而无需“以管理员身份运行”。我应该将这些设置放在注册表中吗?将它们放在 AppData 中是正确的答案吗?如果是,这些设置如何在设置更改应用程序和服务之间共享?

我更像是一名 Web 应用程序开发人员,但在桌面应用程序/服务开发方面还没有太多经验,因此我将不胜感激任何正确方向的观点。

【问题讨论】:

  • 特别是对于使用像LocalSystem 这样无所不能的帐户运行的服务,我会非常警惕非管理员可写入的设置。从安装和升级的角度来看,我认为您不编辑存储在 Program Files 中的文件的决定是一个很好的决定,但我建议在编辑应用程序中嵌入一个清单,以要求管理员权限才能运行它,并让它应用对文件、注册表项或您用于存储的任何内容具有高度限制性的 ACL。
  • 有道理。您能否指出有关嵌入清单和设置 ACL 的任何文档的方向?

标签: c# windows service settings installshield


【解决方案1】:

您可以在应用程序安装目录之外找到 App.Config,并将其放在一个公共文件夹中(如 AppData)。然后,您将告诉您的应用程序从那里加载它,而不是从应用程序安装目录中拉取它。

ConfigurationManager.OpenMappedExeConfig 允许您从自定义位置加载配置。

// Access a configuration file using mapping. 
  // This function uses the OpenMappedExeConfiguration  
  // method to access a new configuration file.    
  // It also gets the custom ConsoleSection and  
  // sets its ConsoleEment BackgroundColor and 
  // ForegroundColor properties to green and red 
  // respectively. Then it uses these properties to 
  // set the console colors.   
  public static void MapExeConfiguration()
  {

    // Get the application configuration file.
    System.Configuration.Configuration config =
      ConfigurationManager.OpenExeConfiguration(
            ConfigurationUserLevel.None);

    Console.WriteLine(config.FilePath);

    if (config == null)
    {
      Console.WriteLine(
        "The configuration file does not exist.");
      Console.WriteLine(
       "Use OpenExeConfiguration to create the file.");
    }

    // Create a new configuration file by saving  
    // the application configuration to a new file. 
    string appName = 
      Environment.GetCommandLineArgs()[0];

    string configFile =  string.Concat(appName, 
      ".2.config");
    config.SaveAs(configFile, ConfigurationSaveMode.Full);

    // Map the new configuration file.
    ExeConfigurationFileMap configFileMap = 
        new ExeConfigurationFileMap();
    configFileMap.ExeConfigFilename = configFile;

    // Get the mapped configuration file
   config = 
      ConfigurationManager.OpenMappedExeConfiguration(
        configFileMap, ConfigurationUserLevel.None);

    // Make changes to the new configuration file.  
    // This is to show that this file is the  
    // one that is used. 
    string sectionName = "consoleSection";

    ConsoleSection customSection =
      (ConsoleSection)config.GetSection(sectionName);

    if (customSection == null)
    {
        customSection = new ConsoleSection();
        config.Sections.Add(sectionName, customSection);
    }
    else 
        // Change the section configuration values.
        customSection =
            (ConsoleSection)config.GetSection(sectionName);

    customSection.ConsoleElement.BackgroundColor =
        ConsoleColor.Green;
    customSection.ConsoleElement.ForegroundColor =
        ConsoleColor.Red;

    // Save the configuration file.
    config.Save(ConfigurationSaveMode.Modified);

    // Force a reload of the changed section. This  
    // makes the new values available for reading.
    ConfigurationManager.RefreshSection(sectionName);

    // Set console properties using the  
    // configuration values contained in the  
    // new configuration file.
    Console.BackgroundColor =
      customSection.ConsoleElement.BackgroundColor;
    Console.ForegroundColor =
      customSection.ConsoleElement.ForegroundColor;
    Console.Clear();

    Console.WriteLine();
    Console.WriteLine("Using OpenMappedExeConfiguration.");
    Console.WriteLine("Configuration file is: {0}", 
      config.FilePath);
  }

样本来源:MSDN

【讨论】:

  • 我相信这就是我想要的。谢谢!
  • 此响应为我指明了正确的方向,但提供的示例代码将配置复制到同一目录(在 Program Files 中)。我使用以下内容将其放入 ProgramData(不是 AppData,这是用户特定的)var configFile = Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData) + "\\" + AppName + "\\App.config";。对于用户特定的配置,您可以使用 SpecialFolder.ApplicationData 而不是 SpecialFolder.CommonApplicationData。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-02-23
  • 1970-01-01
  • 1970-01-01
  • 2011-10-10
相关资源
最近更新 更多