簡體   English   中英

是否可以在無需手動讀取/寫入XMl的情況下修改[appname] .exe.config?

[英]Can I modify [appname].exe.config without having to manually read/write the XMl?

我已經使用.NET 3.5和Visual Studio 2008 Express在C#應用程序中創建了一些設置。 我有許多應用程序范圍的設置,我希望能夠在應用程序中進行修改-我可以通過Properties.Settings.Default訪問它們,但它們只能按預期方式讀取。 我不想讓這些成為用戶范圍的設置,因為它們應該在整個應用程序范圍內。 是否可以在不加載XML以及自己讀取/寫入XML的情況下實現?

我已經看到了使用System.Configuration.ConfigurationManager.OpenExeConfiguration示例,但是config xml的格式與我正在使用的格式不同(這是舊版本的嗎?)

謝謝


編輯

我得出結論,可以這樣做來修改值,但這似乎是一個荒謬的hack。

Configuration config = ConfigurationManager.OpenExeConfiguration(Application.ExecutablePath);
SettingElementCollection settingElements = ((ClientSettingsSection)config.GetSectionGroup("applicationSettings").Sections[0]).Settings;

SettingElement element = settingElements.Get("SettingName");
element.Value.ValueXml.InnerText = "new value";

config.Save(ConfigurationSaveMode.Modified, true);

對於大多數對配置文件的修改, OpenExeConfiguration (或任何其他ConfigurationManager方法)是首選的入口點。 擁有Configuration實例后,您應該獲得要修改的部分,並在修改后調用任何ConfigurationManager.Save方法。 但是,不可能以這種方式檢索applicationSettings部分。

app.config文件中的applicationSettings部分沒有用於更改設置的API。 這樣只能更改用戶范圍的設置。

因此,實際上只有直接操作app.config XML文件才能更改這些設置。

因為從Properties.Settings.Default的索引屬性實際上是可寫的,所以可能會造成一些混亂。 以下內容完全合法:

Properties.Settings.Default["MySetting"] = "New setting value";
Properties.Settings.Default.Save();

但是,該設置將不會保存。

您還可以使用Windows注冊表存儲應用程序特定的狀態。 注冊表中有按用戶和按計算機的密鑰-您可以選擇其中一個或兩個。 例如,某些人在退出時使用注冊表來存儲應用程序窗口的位置和大小。 然后,在重新啟動應用程序時,您可以根據窗口的最后已知大小對其進行定位和調整大小。 這是可以存儲在注冊表中的狀態的一個小示例。

為此,您將使用不同的API進行存儲和檢索。 特別是對Microsoft.Win32.RegistryKey類的SetValue和GetValue調用。 可能有一些有助於將復雜狀態持久保存到注冊表的庫。 如果您有簡單的案例(一些字符串和數字),那么自己動手就很容易。

  private static string _AppRegyPath = "Software\\Vendor Name\\Application Name";

  public Microsoft.Win32.RegistryKey AppCuKey
  {
      get
      {
          if (_appCuKey == null)
          {
              _appCuKey = Microsoft.Win32.Registry.CurrentUser.OpenSubKey(_AppRegyPath, true);
              if (_appCuKey == null)
                  _appCuKey = Microsoft.Win32.Registry.CurrentUser.CreateSubKey(_AppRegyPath);
          }
          return _appCuKey;
      }
      set { _appCuKey = null; }
  }


  private void RetrieveAndApplyState()
  { 
      string s = (string)AppCuKey.GetValue("textbox1Value");
      if (s != null) this.textbox1.Text = s;

      s = (string)AppCuKey.GetValue("Geometry");
      if (!String.IsNullOrEmpty(s))
      {
          int[] p = Array.ConvertAll<string, int>(s.Split(','),
                           new Converter<string, int>((t) => { return Int32.Parse(t); }));
          if (p != null && p.Length == 4)
          {
              this.Bounds = ConstrainToScreen(new System.Drawing.Rectangle(p[0], p[1], p[2], p[3]));
          }
      }
  }

  private void SaveStateToRegistry()
  {
      AppCuKey.SetValue("textbox1Value", this.textbox1.Text);

      int w = this.Bounds.Width;
      int h = this.Bounds.Height;
      int left = this.Location.X;
      int top = this.Location.Y;

      AppCuKey.SetValue("Geometry", String.Format("{0},{1},{2},{3}", left, top, w, h);
  }


  private System.Drawing.Rectangle ConstrainToScreen(System.Drawing.Rectangle bounds)
  {
      Screen screen = Screen.FromRectangle(bounds);
      System.Drawing.Rectangle workingArea = screen.WorkingArea;
      int width = Math.Min(bounds.Width, workingArea.Width);
      int height = Math.Min(bounds.Height, workingArea.Height);
      // mmm....minimax            
      int left = Math.Min(workingArea.Right - width, Math.Max(bounds.Left, workingArea.Left));
      int top = Math.Min(workingArea.Bottom - height, Math.Max(bounds.Top, workingArea.Top));
      return new System.Drawing.Rectangle(left, top, width, height);
  }

該代碼使用Microsoft.Win32.Registry.CurrentUser,因此它設置和檢索用戶特定的應用程序設置。 如果要設置或檢索計算機范圍的狀態,則需要Microsoft.Win32.Registry.LocalMachine。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM