![](/img/trans.png)
[英]Replacing <appname>.exe.config with an AfterBuild doesn't apply to <appname>.vshost.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.