2009-07-16 4 views
2

実行時に変更して保存できるように、アプリケーション設定(接続文字列)を保存する場所と方法を知る必要があります。.NET Winアプリケーションでアプリケーション設定を保存する場所についての混乱

私はVSでプロジェクト>プロパティの設定を構成することができ、アプリインストールディレクトリの下のappname.exe.configファイルに保存されることを知っています。ただし、「アプリケーションスコープ」のものは実行時に読み書きできません。ユーザースコープの下でそれらを変更すると、configファイルのコピーがユーザーディレクトリの下に作成され、アプリケーションの他のユーザーがアクセスすることはありません。

私は、ユーザーが接続文字列を設定し、共通の設定ファイルに保存し、アプリ内からのニーズに応じて、そのマシン上の他のすべてのユーザーにも使用できるようにする必要があります。どうすればこれを達成できますか?

+0

あなたの質問に対する答えは、ユーザー設定を使用する必要があるようです。しかし、あなたはすでにそれらを述べたので、私はあなたの問題が何であるか分かりません。すべてのユーザーに同じ接続文字列を共有させたいが、それをカスタマイズできるようにするか? –

+0

はい。すべてのユーザーが同じ接続文字列を使用してカスタマイズするようにします。 – superartsy

+0

他のコメントの1つでは、アプリケーションを管理したいと思うようです。アクティブディレクトリにいる場合は、アプリケーション管理にグループポリシーを使用できます。データベースが移動された場合、ポリシーが更新され、すべてのユーザーが自動的に更新されます。しかし、必要な努力はおそらくあなたが投資したい以上のものです。 –

答えて

9

最も簡単な方法は、通常のユーザーが読み取り/書き込み権限を持つ共有場所に構成ファイルを作成することです。

設定データ用のパブリックプロパティを持つクラスを作成し、この共有場所でxmlにシリアル化します。

public class Configuration 
{ 
    // config filename 
    private static _name = Path.Combine(
     System.Environment.GetFolderPath(
     Environment.SpecialFolder.CommonApplicationData), 
     @"MyApp\MyConfig.xml"); 

    // the connection string 
    public string ConnectionString {get;set;} 

    // load the configuration from disk 
    public static Configuration Load() 
    { 
    using (var f = File.OpenRead(name)) 
    { 
     var x = new System.Xml.Serialization.XmlSerializer(typeof(Configuration)); 
     return x.Deserialize(f) as Configuration; 
    } 
    } 

    // save the configuration to disk 
    public static Save(Configuration config) 
    { 
    using (var f = File.OpenWrite(name)) 
    { 
     var x = new System.Xml.Serialization.XmlSerializer(typeof(Configuration)); 
     x.Serialize(f, config); 
    } 
    } 
} 
+0

これは唯一のオプションではないかと心配しました。しかし、本当にこれを行う他の簡単な方法はありませんか? – superartsy

+1

私は上記のパスの代わりにEnvironment.SpecialFolder.CommonApplicationDataを使用したいと思いますが、それ以外の方法はありません。 – MusiGenesis

+1

彼は全員の設定がより複雑になるならば、組み込みの機能を活用することができるので、これを行うために標準の設定クラスを使う方が良いと思います。 (ConfigurationManager.OpenExeConfigurationを使用すると、設定ファイルへの任意のパスを使用できます) –

0

レジストリへの読み書きは、ユーザー設定を保存するための推奨方法でしたが、Microsoft.Win32.Registryを使用してこれを簡単に行うことはできますが、このアプローチでは主にさまざまなアクセス許可レジストリの一部に書き込んだり新しいキーを作成したりすることはできません。

+0

レジストリに触れるときにユーザー権利の問題に直面するので、私はこれを避けるでしょう。 – Will

+0

アプリケーションの設定がアプリケーションスコープとユーザースコープに分割されるのと同様に、レジストリはHKEY_LOCAL_MACHINEとHKEY_CURRENT_USERに分割されます。アプリケーションの設定をレジストリに切り替えることは、特権に関する問題を回避するのに役立ちません。 –

+0

レジストリのユーザー側に書いたのが実際にうまくいくでしょうが、Askerは実際にはどのユーザーも変更できるグローバル設定を望んでいると思います。 – MusiGenesis

5

アプリケーションスコープの接続文字列は書き込み可能ですが、使用する文字列を取得するのとは別の方法が必要です。例:

Configuration c = ConfigurationManager 
    .OpenExeConfiguration(ConfigurationUserLevel.None); 

c.ConnectionStrings.ConnectionStrings["myConnectionString"] 
    .ConnectionString = "theConnectionString"; 
c.Save(); 

また、変更が適切に取得されるようにセクションをリフレッシュする必要があります。直後:

+0

これはVistaのUAC環境下でも動作しますか? – superartsy

+2

基本ファイルシステムに必要な権限がない限り、設定ファイルを保存することはできません。 –

+1

ユーザーが管理者アクセス権を持っている場合のみ、シングルユーザーコンピュータでのアクセスは非常に困難です。 (マルチユーザーのコンピュータの場合は、管理者にこの設定を変更させてもらいたい) –

0

あなたは、あなたの問題のいくつかの相反する要素を持っている:彼らは実行時に変更して保存することができるように

アプリケーション設定(接続文字列)が保存することができました。

適用範囲」のものは、実行時に読み取り/書き込み、あなたが設定ファイルのコピーは、ユーザーディレクトリの下に作成され、文句を言わないアプリケーションの他のユーザーがアクセスすることが、ユーザのスコープの下のものを変更した場合はされていません。

ベスト・プラクティスはあなたはに適用する(接続文字列など)の設定は、システムのすべてのユーザーがないは、システムの任意のランダムなユーザーによって変更可能でなければならないこと。設定のその種の必要があります口述します管理する資格のある人によって変更されるシステム。

したがって、あなたが記述している動作は、まさに意図されているものです。ユーザーが実際にこれを変更できるようにしたい場合は、ユーザー設定にしてください。ユーザーがそれをねじ込むと、自分のアカウントのためにねじ込むだけです。

+0

はい、あなたは正しいです、誰に影響を与える何かは、authority.Moreだけで変更する必要があります。私たちが話している「使用後の変化」は、「初期設定」です。デプロイされたら、ユーザーと簡単なフォームを使って、接続したいサーバーとデータベースを選択することができます。これは通常、一度だけ発生します。ネットワークが何らかの変更を受けたとします。 – superartsy

+0

そして、各ユーザーにそれをさせるのに間違っているのは何ですか? –

1

私のやり方は、SQL接続情報を持つPOCOオブジェクトから直列化されたXMLファイルを隔離されたストレージに保存したことです。そこから読み書きできるユーザーアカウントには実際の制限がないので、ユーザーのアクセス許可について心配する必要はありません。

次に、接続文字列プロパティがアプリケーション設定ファイルから読み込まれたときに、XMLファイルを独立した記憶域にデシリアライズし、接続文字列を作成して、それをアプリケーション設定接続文字列に挿入するように設定イベントを変更しましたプロパティ。私は設定クラスそのものの中でこれを行っていたので、ファイルに書き込むことはできませんでしたが、ファイルに保存することはできませんでした。

私のアプリケーションを実行すると、サーバーに接続できない場合は、SQL Server情報を要求するウィンドウがポップアップして入力され、それを入力すると隔離されたストレージに保存されます再度(アップグレードしても)

クライアントアプリケーション(WPFまたはWinForms)を使用している場合、他のマシンのユーザーはこれを使用することはできません.Net Remotingなどを調べない限り、おそらく解決策は見つけられません。その性質。ただし、WinForms AppのSAMEマシンに複数のユーザーがいる場合は、IsolatedStorageを使用することができ、すべてのユーザーに使用できます。設定クラスで

、このイベントハンドラを追加:他のあなたは上の共有の場所を作成する必要が指摘したように

protected override void OnSettingsLoaded(object sender, System.Configuration.SettingsLoadedEventArgs e) 
{ 
    base.OnSettingsLoaded(sender, e); 
    this["MyAppConnectionString"] = MyLibrary.BuildConnectionString(); 
} 
+0

私はこれが好きです!物事を行う独特の方法です。私は1つのマイナーな問題を参照してください。設定を保存するためにシリアライズ可能なクラスを使用する場合、常にバージョニングの問題が発生する可能性があります。 Common_AppDataフォルダに隔離されたストレージを選択した理由もあります。 – superartsy

+0

バージョン管理では、設定を保存する方法によって異なります。デシリアライズ時にプロパティを追加すると、ほとんどの場合、そのプロパティはnullとして読み込まれるため、問題ではありません。あなたの走行距離は変わります。これらのクラスには、接続文字列の設定やプリンタ設定の保存などのためにのみプロパティを使用するため、プロパティを頻繁に追加することはありません。私たちは孤立したストレージを選択します。なぜなら、誰にも見えない「隠された」すべてのものに書き込み可能なものだったからです。 – TheCodeMonk

2

VB:

Private Sub MySettings_SettingsLoaded(ByVal sender As Object, ByVal e As System.Configuration.SettingsLoadedEventArgs) Handles Me.SettingsLoaded 
    Me.Item("MyAppConnectionString") = MyLibrary.BuildConnectionString() 
End Sub 

のC#をアプリケーションのすべてのユーザーが書き込み可能なコンピュータ。この場所は、フォルダ、ファイル、またはレジストリにすることができます。しかし、Windowsには実際にこの場所があります。これについて詳しくはMSDNで読むことができます。あなたが必要とするフォルダは、共通のアプリケーション・データのためにある:

CSIDL_COMMON_APPDATA

このフォルダには、ユーザー固有のものではないアプリケーションデータのために使用すべきです。たとえば、アプリケーションでCSIDL_COMMON_APPDATAフォルダにスペルチェック辞書、クリップアートのデータベース、またはログファイルを格納することができます。この情報はローミングされず、コンピュータを使用するすべての人が利用できます。デフォルトでは、この場所は通常の(管理者でない、非電源の)ユーザーに対しては読み取り専用です。アプリケーションで通常のユーザーにCSIDL_COMMON_APPDATAのアプリケーション固有のサブディレクトリへの書き込みアクセスが必要な場合、アプリケーションはアプリケーションのセットアップ中にそのサブディレクトリのセキュリティを明示的に変更する必要があります。修正されたセキュリティは、ベンダーアンケートに文書化されなければならない。

あなたの.NETアプリケーションで

Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData); 

を呼び出すことで、このフォルダの場所を取得することができます。 Vistaの場合、このフォルダは通常C:\ProgramDataです。

共有フォルダ内に独自のベンダーとアプリケーション固有のフォルダを作成する必要があります。これは、昇格された権限で実行されているインストールプログラムで行う必要があります。このインストールプログラムは、ユーザーが上記の引用符で見られるように書き込みアクセス権を得るために必要な特権を持っていることを確認する必要があります。

+0

ありがとうございます。私はこれについて知っていて、このディレクトリ構造の下に共通のファイルを保存するアプリケーションもあります。しかし、ここで設定プロパティを保存するには、自分でそれらを読み書きしなければならないということです。私はもっ​​と簡単な方法を見逃していたかどうか疑問に思っていました。 – superartsy

関連する問題