2009-05-15 7 views
4

.NET 3.5とVisual Studio 2008 Expressを使用してC#アプリケーションでいくつかの設定を作成しました。私は、アプリケーション内から変更可能にしたいアプリケーションスコープの設定をいくつか持っています - 私はProperties.Settings.Defaultを通してそれらにアクセスできますが、それらは期待どおりにしか読み込まれません。私はこれらをアプリケーション全体に適用する必要があるため、ユーザースコープの設定にする必要はありません。 XMLを読み込んだり読み書きしたりすることなく、これは可能ですか?[appname] .exe.configは、手動でXMlを読み書きすることなく変更できますか?

(これは古いバージョンからでしょうか?)私はSystem.Configuration.ConfigurationManager.OpenExeConfigurationを用いた例を見てきましたが、設定XMLは、私が使用していたとは異なるフォーマットであることになりそうだ

おかげ


編集

私はこれを行う値を変更することができましたが、ばかげたハックのようです。

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); 

答えて

1

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(); 

ただし、設定は保存されません。

+0

そして、設定ファイルのアクセス許可を忘れないでください。 app.exe.configは管理者のみに書き込み可能であることが必要です。 – Richard

+0

ありがとうございます。Properties.Settings.Defaultで設定を取得するにはどのセクションが必要ですか? –

+0

私は十分にあなたの質問を読んでいないことがわかります。私が提案する方法は、設定ファイルの一般的な変更です。アセンブリスコープの設定を変更する別の(より良い)方法を示すために私の答えを更新しました。 –

1

Windowsのレジストリを使用して、アプリケーション固有の状態を保存することもできます。レジストリには、ユーザー単位およびマシン単位のキーがあり、どちらかまたは両方を使用できます。たとえば、退出時にアプリケーションウィンドウの場所とサイズを格納するためにレジストリを使用する人がいます。その後、アプリを再起動すると、最後の既知のサイズに従ってウィンドウの位置とサイズを設定できます。これは、レジストリに格納できる状態の種類の小さな例です。

これを行うには、保存と検索に異なるAPIを使用します。特にSetValueとGetValueはMicrosoft.Win32.RegistryKeyクラスを呼び出します。レジストリに複雑な状態を持続させるのに役立つライブラリがあるかもしれません。シンプルなケース(文字列と数字がいくつかあります)があれば、それを自分で行うのは簡単です。コードはMicrosoft.Win32.Registry.CurrentUserを使用し、そしてそれは、ユーザ固有のアプリの設定を設定し、取得するように

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.LocalMachineが必要です。

関連する問題