┏第33号━━━━━━━━━━━━━━━━━━━━━━━━━━┓ ┃         .NETプログラミング研究         ┃ ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ ──<メニュー>─────────────────────── ■.NET Tips ・アプリケーションの設定を保存する ─────────────────────────────── ─────────────────────────────── ■.NET Tips ─────────────────────────────── ●アプリケーションの設定を保存する アプリケーション終了時に設定を保存しておき、次の起動時に設定を 読み込むといった処理を行うためには、設定の情報をファイルに書き 込むか、レジストリに書き込むかのどちらかの方法を選ぶことになる でしょう。ここではアプリケーションの設定を保存、復元するための 様々な方法を考えます。 ★設定はクラスで管理する アプリケーションの設定は、それぞれの設定を別個の変数に入れてお くのではなく、すべての設定を一つのクラスにまとめ、そのプロパテ ィとして管理するようにしておくと、何かと便利です。例えば、 "Settings"のようなクラスを作成し、アプリのすべての設定がこのク ラスのプロパティで取得、設定できるようにします。 ここでは、次のような"Settings"クラスを作成し、このクラスでアプ リの全設定を管理するものとします。(ここでは2つのプロパティしか ありませんが。) ‥‥▽VB.NET ここから▽‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ Public Class Settings Private _text As String Private _number As Integer Public Property Text() As String Get Return _text End Get Set(ByVal Value As String) _text = Value End Set End Property Public Property Number() As Integer Get Return _number End Get Set(ByVal Value As Integer) _number = Value End Set End Property Public Sub New() _text = "Text" _number = 0 End Sub End Class ‥‥△VB.NET ここまで△‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ ‥‥▽C# ここから▽‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ public class Settings { private string _text; private int _number; public string Text { get {return _text;} set {_text = value;} } public int Number { get {return _number;} set {_number = value;} } public Settings() { _text = "Text"; _number = 0; } } ‥‥△C# ここまで△‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ ★ファイルに保存する 設定をファイルに保存する方法としては、Windowsでは伝統的にINIフ ァイルが使用されてきました。しかし.NET FrameworkではXMLを扱う機 能が充実しており、INIファイルではなく、XMLで保存すべきです。 -<補足>- それでもINIファイルを使わなければならない場合もあるでしょう。. NET FrameworkでINIファイルへの保存、復元を行うには、INIファイル をテキストファイルとして扱うか、あるいはWin32 APIの GetPrivateProfileString、WritePrivateProfileString関数などを使 うかということになるでしょう。 なお、.NET FrameworkでINIファイルを扱うためのクラスがいくつか公 開されていますので、これらを使わせていただくのもよいでしょう。 ここでは2つ紹介させていただきます。 [URL]The Code Project - IniFile Class using VB.NET http://www.codeproject.com/vb/net/VbNetClassIniFile.asp [URL]The Code Project - An INI file handling class using C# http://www.codeproject.com/csharp/cs_ini.asp -------- .NET FrameworkでXMLの編集を行うには、通常XmlDocumentクラスを使 います。しかし、DOBON.NETで紹介されている「オブジェクトの内容を XMLファイルに保存、復元する」のように、アプリの設定を管理してい るクラスのインスタンスをXmlSerializerを使ったシリアル化によりフ ァイルに書き込めば、より簡単に保存することができるでしょう。 [URL]オブジェクトの内容をXMLファイルに保存、復元する http://dobon.net/vb/dotnet/file/xmlserializer.html Settingsオブジェクト"appSettings"をXMLファイルに保存し、復元す る簡単なコードを以下に示します。 ‥‥▽VB.NET ここから▽‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ Dim appSettings As New Settings '保存先のファイル名 Dim fileName As String = "C:\settings.config" '<XMLファイルに書き込む> 'XmlSerializerオブジェクトを作成 '書き込むオブジェクトの型を指定する Dim serializer1 As New System.Xml.Serialization.XmlSerializer( _ GetType(Settings)) 'ファイルを開く Dim fs1 As New System.IO.FileStream( _ fileName, System.IO.FileMode.Create) 'シリアル化し、XMLファイルに保存する serializer1.Serialize(fs1, appSettings) '閉じる fs1.Close() '<XMLファイルから読み込む> 'XmlSerializerオブジェクトの作成 Dim serializer2 As New System.Xml.Serialization.XmlSerializer( _ GetType(Settings)) 'ファイルを開く Dim fs2 As New System.IO.FileStream( _ fileName, System.IO.FileMode.Open) 'XMLファイルから読み込み、逆シリアル化する appSettings = CType(serializer2.Deserialize(fs2), Settings) '閉じる fs2.Close() ‥‥△VB.NET ここまで△‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ ‥‥▽C# ここから▽‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ Settings appSettings = new Settings(); //保存先のファイル名 string fileName = "C:\\settings.config"; //<XMLファイルに書き込む> //XmlSerializerオブジェクトを作成 //書き込むオブジェクトの型を指定する System.Xml.Serialization.XmlSerializer serializer1 = new System.Xml.Serialization.XmlSerializer(typeof(Settings)); //ファイルを開く System.IO.FileStream fs1 = new System.IO.FileStream(fileName, System.IO.FileMode.Create); //シリアル化し、XMLファイルに保存する serializer1.Serialize(fs1, appSettings); //閉じる fs1.Close(); //<XMLファイルから読み込む> //XmlSerializerオブジェクトの作成 System.Xml.Serialization.XmlSerializer serializer2 = new System.Xml.Serialization.XmlSerializer(typeof(Settings)); //ファイルを開く System.IO.FileStream fs2 = new System.IO.FileStream(fileName, System.IO.FileMode.Open); //XMLファイルから読み込み、逆シリアル化する appSettings = (Settings) serializer2.Deserialize(fs2); //閉じる fs2.Close(); ‥‥△C# ここまで△‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ アプリの設定をテキストファイルに保存する欠点として、その内容を ユーザーが自由に編集できてしまうという点があります。それを防ぐ ためには、バイナリファイルに書き込む方法が考えられます。(さら に、バイナリファイルを使ったほうが一般的に読み込み、書込みが速 いです。) オブジェクトの内容をバイナリファイルに保存する簡単な方法として、 BinaryFormatterクラスを使う方法が挙げられます。BinaryFormatter を使用してオブジェクトをシリアル化し、FileStreamでファイルに書 き込むのです。 まず、SettingsオブジェクトをBinaryFormatterでシリアル化できるよ うにするために、SettingsクラスにSerializableAttribute属性を付加 する必要があります。 ‥‥▽VB.NET ここから▽‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ _ Public Class Settings '(省略) End Class ‥‥△VB.NET ここまで△‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ ‥‥▽C# ここから▽‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ [Serializable()] public class Settings { //(省略) } ‥‥△C# ここまで△‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ Settingsオブジェクト"appSettings"をバイナリファイルに保存し、復 元する簡単なコードを以下に示します。 ‥‥▽VB.NET ここから▽‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ 'Imports System.Runtime.Serialization 'Imports System.Runtime.Serialization.Formatters.Binary 'が先頭に書かれているものとする Dim appSettings As New Settings '保存先のファイル名 Dim fileName As String = "C:\settings.config" '<バイナリファイルに書き込む> 'BinaryFormatterオブジェクトを作成 Dim bf1 As New BinaryFormatter 'ファイルを開く Dim fs1 As New System.IO.FileStream( _ fileName, System.IO.FileMode.Create) 'シリアル化し、バイナリファイルに保存する bf1.Serialize(fs1, appSettings) '閉じる fs1.Close() '<バイナリファイルから読み込む> 'BinaryFormatterオブジェクトの作成 Dim bf2 As New BinaryFormatter 'ファイルを開く Dim fs2 As New System.IO.FileStream( _ fileName, System.IO.FileMode.Open) 'バイナリファイルから読み込み、逆シリアル化する appSettings = CType(bf2.Deserialize(fs2), Settings) '閉じる fs2.Close() ‥‥△VB.NET ここまで△‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ ‥‥▽C# ここから▽‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ //using System.Runtime.Serialization; //using System.Runtime.Serialization.Formatters.Binary; //が先頭に書かれているものとする Settings appSettings = new Settings(); //保存先のファイル名 string fileName = "C:\\settings.config"; //<バイナリファイルに書き込む> //BinaryFormatterオブジェクトを作成 BinaryFormatter bf1 = new BinaryFormatter(); //ファイルを開く System.IO.FileStream fs1 = new System.IO.FileStream(fileName, System.IO.FileMode.Create); //シリアル化し、バイナリファイルに保存する bf1.Serialize(fs1, appSettings); //閉じる fs1.Close(); //<バイナリファイルから読み込む> //BinaryFormatterオブジェクトの作成 BinaryFormatter bf2 = new BinaryFormatter(); //ファイルを開く System.IO.FileStream fs2 = new System.IO.FileStream(fileName, System.IO.FileMode.Open); //バイナリファイルから読み込み、逆シリアル化する appSettings = (Settings) bf2.Deserialize(fs2); //閉じる fs2.Close(); ‥‥△C# ここまで△‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ 補足:設定をファイルに保存する方法として、アプリケーション構成 ファイルを使用する方法を考えた方もいらっしゃるかもしれません。 しかしアプリケーション構成ファイルは読み込み専用ですので、アプ リの設定の保存方法としては適切ではありません。 [URL]「アプリケーション構成ファイル」を使用して設定を読み込む http://dobon.net/vb/dotnet/programing/appconfigfile.html ★レジストリに保存する 設定を保存する方法として推奨されているのは、レジストリに保存す る方法です。ファイルを使用した場合と比べ、レジストリに書き込ま れた情報はユーザーによって編集、削除される恐れが少なく、書込み や読み込みが通常はより高速です。ただ、特に簡単なツールのような アプリの場合、レジストリに設定を書き込むアプリを好ましく思わな いユーザーが多いことも事実です。 レジストリにデータを書き込み、読み込む方法を簡単に紹介しておき ます。詳しくは、DOBON.NETの「レジストリの操作」をご覧ください。 [URL]レジストリの操作 http://dobon.net/vb/dotnet/system/registrykey.html 次のコードは、"HKEY_CURRENT_USER\Software\test\subkey"のキー "key"に値"KeyValue"を書き込み、さらに読み込むものです。 ‥‥▽VB.NET ここから▽‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ '<レジストリに書き込む> 'サブキーを開く Dim regkey1 As Microsoft.Win32.RegistryKey = _ Microsoft.Win32.Registry.CurrentUser.CreateSubKey( _ "Software\test\subkey") '文字列を書き込む regkey1.SetValue("key", "KeyValue") '閉じる regkey1.Close() '<レジストリから読み込む> 'サブキーを読み取り専用で開く Dim regkey2 As Microsoft.Win32.RegistryKey = _ Microsoft.Win32.Registry.CurrentUser.OpenSubKey( _ "Software\test\subkey", False) '文字列を読み込む Dim stringValue As String = CType(regkey2.GetValue("key"), String) '閉じる regkey2.Close() ‥‥△VB.NET ここまで△‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ ‥‥▽C# ここから▽‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ //<レジストリに書き込む> //サブキーを開く Microsoft.Win32.RegistryKey regkey1 = Microsoft.Win32.Registry.CurrentUser.CreateSubKey( @"Software\test\subkey"); //文字列を書き込む regkey1.SetValue("key", "KeyValue"); //閉じる regkey1.Close(); //<レジストリから読み込む> //サブキーを読み取り専用で開く Microsoft.Win32.RegistryKey regkey2 = Microsoft.Win32.Registry.CurrentUser.OpenSubKey( @"Software\test\subkey", false); //文字列を読み込む string stringValue = (string) regkey2.GetValue("key"); //閉じる regkey2.Close(); ‥‥△C# ここまで△‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ ★シリアル化してレジストリに保存する 設定をファイルに保存する方法では、オブジェクトのシリアル化を利 用することにより、より簡単に保存することができました。レジスト リへの保存も同じようにできないものでしょうか? この一つの答えが、Windows Forms FAQの「How do you persist any object in the registry」で紹介されています。 [URL]How do you persist any object in the registry http://www.syncfusion.com/faq/winforms/search/34.asp ここで紹介されている方法は、BinaryFormatterによりオブジェクトを シリアル化し、得られたバイト型配列をレジストリに書き込むという ものです。この方法によりSettingsオブジェクト"appSettings"をレジ ストリに保存し、復元するコードの例を以下に示します。 ‥‥▽VB.NET ここから▽‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ 'Imports System.IO 'Imports System.Runtime.Serialization 'Imports System.Runtime.Serialization.Formatters.Binary 'が先頭に書かれているものとする Dim appSettings As New Settings '<レジストリに書き込む> Dim ms1 As New MemoryStream Dim bf1 As New BinaryFormatter 'シリアル化してMemoryStreamに書き込む bf1.Serialize(ms1, appSettings) 'レジストリへ保存する Dim regkey1 As Microsoft.Win32.RegistryKey = _ Microsoft.Win32.Registry.CurrentUser.CreateSubKey( _ "Software\test\subkey") regkey1.SetValue("Settings", ms1.ToArray()) '閉じる ms1.Close() regkey1.Close() '<レジストリから読み込む> Dim bf2 As New BinaryFormatter 'レジストリから読み込む Dim regkey2 As Microsoft.Win32.RegistryKey = _ Microsoft.Win32.Registry.CurrentUser.OpenSubKey( _ "Software\test\subkey", False) Dim bs As Byte() = CType(regkey2.GetValue("Settings"), Byte()) '逆シリアル化して復元 Dim ms2 As New MemoryStream(bs, False) appSettings = CType(bf2.Deserialize(ms2), Settings) '閉じる ms2.Close() regkey2.Close() ‥‥△VB.NET ここまで△‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ ‥‥▽C# ここから▽‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ //using System.IO; //using System.Runtime.Serialization; //using System.Runtime.Serialization.Formatters.Binary; //が先頭に書かれているものとする Settings appSettings = new Settings(); //<レジストリに書き込む> MemoryStream ms1 = new MemoryStream(); BinaryFormatter bf1 = new BinaryFormatter(); //シリアル化してMemoryStreamに書き込む bf1.Serialize(ms1, appSettings); //レジストリへ保存する Microsoft.Win32.RegistryKey regkey1 = Microsoft.Win32.Registry.CurrentUser.CreateSubKey( @"Software\test\subkey"); regkey1.SetValue("Settings", ms1.ToArray()); //閉じる ms1.Close(); regkey1.Close(); //<レジストリから読み込む> BinaryFormatter bf2 = new BinaryFormatter(); //レジストリから読み込む Microsoft.Win32.RegistryKey regkey2 = Microsoft.Win32.Registry.CurrentUser.OpenSubKey( @"Software\test\subkey", false); byte[] bs = (byte[]) regkey2.GetValue("Settings"); //逆シリアル化して復元 MemoryStream ms2 = new MemoryStream(bs, false); appSettings = (Settings) bf2.Deserialize(ms2); //閉じる ms2.Close(); regkey2.Close(); ‥‥△C# ここまで△‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ ★シリアル化の欠点 設定を保存する時、設定オブジェクトをシリアル化して保存するやり 方は、簡単、便利である反面、新しくプロパティを加えるとそれ以前 に保存したファイルから設定を復元できなくなるという欠点がありま す。つまり、バージョンアップにより新しい設定が増え、設定クラス に新しいプロパティが増えると、前のバージョンの設定が全く読み込 めなくなります。 これを回避するためには、シリアル化せずに一つ一つの設定を保存、 復元する、設定をHashtableのようなコレクションで管理する、あるい は、DataSetとして設定を管理し、WriteXml、ReadXmlメソッドで書き 込み、読み込みをするなどの方法が考えられます。 ★設定をどこに保存するか? 設定を保存する方法をいろいろ紹介しましたが、設定をいったいどの フォルダ、またはレジストリキーに保存するかという問題が残ってい ます。この問題を解決するためのプロパティがApplicationクラスにあ ります。 設定をレジストリに書き込むとき、書き込むのに適切なレジストリキー は、ApplicationクラスのUserAppDataRegistryまたは CommonAppDataRegistryプロパティで取得できます。 UserAppDataRegistryプロパティは、ユーザー別に設定を保存するため に使用します。具体的には、 HKEY_CURRENT_USER\Software\[CompanyName]\[ProductName] \[ProductVersion] というキーのRegistryKeyオブジェクトを返します([CompanyName]、 [ProductName]、[ProductVersion]はそれぞれアプリケーションの CompanyName、ProductName、ProductVersionです)。 CommonAppDataRegistryプロパティは、ユーザー共通の設定を保存する ために使用します。具体的には、 HKEY_LOCAL_MACHINE\Software\[CompanyName]\[ProductName] \[ProductVersion] というキーのRegistryKeyオブジェクトを返します。 つまり、UserAppDataRegistryとCommonAppDataRegistryの違いは、ルー トキーがHKEY_CURRENT_USERかHKEY_LOCAL_MACHINEかの違いです。通常 のアプリの設定は、UserAppDataRegistryを使って保存すればよいでし ょう。 また、設定をファイルに書き込むとき、そのファイルを保存するのに 適切なフォルダのパスはApplicationクラスのUserAppDataPath、 LocalUserAppDataPath、CommonAppDataPathプロパティで取得できます。 UserAppDataPathプロパティは、ユーザーのアプリケーションデータの パスを返しますので、ユーザー別に設定を保存するために使用します。 具体的には、例えば、 C:\Documents and Settings\[UserName]\Application Data \[CompanyName]\[ProductName]\[ProductVersion] のようなフォルダのパスを返します([UserName]はユーザー名です)。 LocalUserAppDataPathプロパティは、非ローミングユーザーのアプリ ケーションデータのパスを返します。具体的には、例えば、 C:\Documents and Settings\[UserName]\Local Settings \Application Data\[CompanyName]\[ProductName]\[ProductVersion] のようなフォルダのパスを返します。 CommonAppDataPathプロパティは、すべてのユーザーが共有する設定を 保存するために使用します。具体的には、例えば、 C:\Documents and Settings\All Users\Application Data \[CompanyName]\[ProductName]\[ProductVersion] のようなフォルダのパスを返します。 通常のアプリの保存先としては、UserAppDataPathプロパティが返すパ スを使えばよいでしょう。 ここで紹介したプロパティが返すパスは、すべて最後にアプリのバー ジョンが付いています。これはつまり、これらをそのまま使って設定 を保存すると、バージョンごとに設定の保存先が変わるため、バージ ョンが変わると、前の設定を読み込めないということになります。こ れでは困るという時は、保存場所を自分で決めるか、バージョンが変 わった時に、前のバージョンの設定を移動するようにするなどの工夫 が必要になるでしょう。 補足1:ここで紹介したプロパティから値を取得する時に、そのレジス トリキーあるいはフォルダが存在しなかった場合、勝手に作成されま す。 補足2:ここで紹介したプロパティは、そのパスにアセンブリの会社名 や製品名をそのまま使って生成しているため、アセンブリの会社名や 製品名にファイル名として使えない文字が含まれている場合はエラー が発生しますし、"\"が使われている場合は予期せぬパスとなってしま います。よって、アセンブリの会社名や製品名に不適切な文字が含ま れていないことを確かにしてから、これらのプロパティを使用する必 要があります。 ★まとめ 以上の知識を元にして、Settingsクラスを作り直してみます。 まず、SettingsクラスのインスタンスをSettingsクラスの静的プロパ ティ"Instance"で取得できるようにします。 さらに、Settingsクラスの静的メソッドにより、XMLファイル、バイナ リファイル、さらにレジストリへの設定の保存と復元ができるように しています。なお保存先のパスは、バージョンに依存しない場所にし ています。 ‥‥▽VB.NET ここから▽‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ Imports System Imports System.IO Imports System.Runtime.Serialization Imports System.Runtime.Serialization.Formatters.Binary Imports System.Windows.Forms Imports Microsoft.Win32 _ Public Class Settings '設定を保存するフィールド Private _text As String Private _number As Integer '設定のプロパティ Public Property Text() As String Get Return _text End Get Set(ByVal Value As String) _text = Value End Set End Property Public Property Number() As Integer Get Return _number End Get Set(ByVal Value As Integer) _number = value End Set End Property 'コンストラクタ Public Sub New() _text = "Text" _number = 0 End Sub 'Settingsクラスのただ一つのインスタンス _ Private Shared _instance As Settings _ Public Shared Property Instance() As Settings Get If _instance Is Nothing Then _instance = New Settings End If Return _instance End Get Set(ByVal Value As Settings) _instance = Value End Set End Property ''' ''' 設定をXMLファイルから読み込み復元する ''' Public Shared Sub LoadFromXmlFile() Dim p As String = GetSettingPath() Dim fs As New FileStream( _ p, FileMode.Open, FileAccess.Read) Dim xs As New System.Xml.Serialization.XmlSerializer( _ GetType(Settings)) '読み込んで逆シリアル化する Dim obj As Object = xs.Deserialize(fs) fs.Close() Instance = CType(obj, Settings) End Sub ''' ''' 現在の設定をXMLファイルに保存する ''' Public Shared Sub SaveToXmlFile() Dim p As String = GetSettingPath() Dim fs As New FileStream( _ p, FileMode.Create, FileAccess.Write) Dim xs As New System.Xml.Serialization.XmlSerializer( _ GetType(Settings)) 'シリアル化して書き込む xs.Serialize(fs, Instance) fs.Close() End Sub ''' ''' 設定をバイナリファイルから読み込み復元する ''' Public Shared Sub LoadFromBinaryFile() Dim p As String = GetSettingPath() Dim fs As New FileStream( _ p, FileMode.Open, FileAccess.Read) Dim bf As New BinaryFormatter '読み込んで逆シリアル化する Dim obj As Object = bf.Deserialize(fs) fs.Close() Instance = CType(obj, Settings) End Sub ''' ''' 現在の設定をバイナリファイルに保存する ''' Public Shared Sub SaveToBinaryFile() Dim p As String = GetSettingPath() Dim fs As New FileStream( _ p, FileMode.Create, FileAccess.Write) Dim bf As New BinaryFormatter 'シリアル化して書き込む bf.Serialize(fs, Instance) fs.Close() End Sub ''' ''' 設定をレジストリから読み込み復元する ''' Public Shared Sub LoadFromRegistry() Dim bf As New BinaryFormatter 'レジストリから読み込む Dim reg As RegistryKey = GetSettingRegistry() Dim bs As Byte() = CType(reg.GetValue(""), Byte()) '逆シリアル化して復元 Dim ms As New MemoryStream(bs, False) Instance = CType(bf.Deserialize(ms), Settings) '閉じる ms.Close() reg.Close() End Sub ''' ''' 現在の設定をレジストリに保存する ''' Public Shared Sub SaveToRegistry() Dim ms As New MemoryStream Dim bf As New BinaryFormatter 'シリアル化してMemoryStreamに書き込む bf.Serialize(ms, Instance) 'レジストリへ保存する Dim reg As RegistryKey = GetSettingRegistry() reg.SetValue("", ms.ToArray()) '閉じる ms.Close() reg.Close() End Sub Private Shared Function GetSettingPath() As String Dim p As String = Path.Combine( _ Environment.GetFolderPath( _ Environment.SpecialFolder.ApplicationData), _ Application.CompanyName + "\" + Application.ProductName _ + "\" + Application.ProductName + ".config") Return p End Function Private Shared Function GetSettingRegistry() As RegistryKey Dim reg As RegistryKey = _ Registry.CurrentUser.CreateSubKey( _ ("Software\" + Application.CompanyName + _ "\" + Application.ProductName)) Return reg End Function End Class ‥‥△VB.NET ここまで△‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ ‥‥▽C# ここから▽‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ using System; using System.IO; using System.Runtime.Serialization; using System.Runtime.Serialization.Formatters.Binary; using System.Windows.Forms; using Microsoft.Win32; [Serializable()] public class Settings { //設定を保存するフィールド private string _text; private int _number; //設定のプロパティ public string Text { get {return _text;} set {_text = value;} } public int Number { get {return _number;} set {_number = value;} } //コンストラクタ public Settings() { _text = "Text"; _number = 0; } //Settingsクラスのただ一つのインスタンス [NonSerialized()] private static Settings _instance; [System.Xml.Serialization.XmlIgnore] public static Settings Instance { get { if (_instance == null) _instance = new Settings(); return _instance; } set {_instance = value;} } /// /// 設定をXMLファイルから読み込み復元する /// public static void LoadFromXmlFile() { string path = GetSettingPath(); FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read); System.Xml.Serialization.XmlSerializer xs = new System.Xml.Serialization.XmlSerializer( typeof(Settings)); //読み込んで逆シリアル化する object obj = xs.Deserialize(fs); fs.Close(); Instance = (Settings) obj; } /// /// 現在の設定をXMLファイルに保存する /// public static void SaveToXmlFile() { string path = GetSettingPath(); FileStream fs = new FileStream(path, FileMode.Create, FileAccess.Write); System.Xml.Serialization.XmlSerializer xs = new System.Xml.Serialization.XmlSerializer( typeof(Settings)); //シリアル化して書き込む xs.Serialize(fs, Instance); fs.Close(); } /// /// 設定をバイナリファイルから読み込み復元する /// public static void LoadFromBinaryFile() { string path = GetSettingPath(); FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read); BinaryFormatter bf = new BinaryFormatter(); //読み込んで逆シリアル化する object obj = bf.Deserialize(fs); fs.Close(); Instance = (Settings) obj; } /// /// 現在の設定をバイナリファイルに保存する /// public static void SaveToBinaryFile() { string path = GetSettingPath(); FileStream fs = new FileStream(path, FileMode.Create, FileAccess.Write); BinaryFormatter bf = new BinaryFormatter(); //シリアル化して書き込む bf.Serialize(fs, Instance); fs.Close(); } /// /// 設定をレジストリから読み込み復元する /// public static void LoadFromRegistry() { BinaryFormatter bf = new BinaryFormatter(); //レジストリから読み込む RegistryKey reg = GetSettingRegistry(); byte[] bs = (byte[]) reg.GetValue(""); //逆シリアル化して復元 MemoryStream ms = new MemoryStream(bs, false); Instance = (Settings) bf.Deserialize(ms); //閉じる ms.Close(); reg.Close(); } /// /// 現在の設定をレジストリに保存する /// public static void SaveToRegistry() { MemoryStream ms = new MemoryStream(); BinaryFormatter bf = new BinaryFormatter(); //シリアル化してMemoryStreamに書き込む bf.Serialize(ms, Instance); //レジストリへ保存する RegistryKey reg = GetSettingRegistry(); reg.SetValue("", ms.ToArray()); //閉じる ms.Close(); reg.Close(); } private static string GetSettingPath() { string path = Path.Combine( Environment.GetFolderPath( Environment.SpecialFolder.ApplicationData), Application.CompanyName + "\\" + Application.ProductName + "\\" + Application.ProductName + ".config"); return path; } private static RegistryKey GetSettingRegistry() { RegistryKey reg = Registry.CurrentUser.CreateSubKey( "Software\\" + Application.CompanyName + "\\" + Application.ProductName); return reg; } } ‥‥△C# ここまで△‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ このクラスを使用して設定をXMLファイルに保存、復元するには、次の ようにします。(設定を読み込む時、保存されたデータが無い場合は エラーが出ます。) ‥‥▽VB.NET ここから▽‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ '設定を変更する Settings.Instance.Number = 123 Settings.Instance.Text = "こんにちは" '現在の設定をXMLファイルに保存する Settings.SaveToRegistry() 'XMLファイルから設定を読み込む Settings.LoadFromRegistry() ‥‥△VB.NET ここまで△‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ ‥‥▽C# ここから▽‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ //設定を変更する Settings.Instance.Number = 123; Settings.Instance.Text = "こんにちは"; //現在の設定をXMLファイルに保存する Settings.SaveToRegistry(); //XMLファイルから設定を読み込む Settings.LoadFromRegistry(); ‥‥△C# ここまで△‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ ★最後に アプリケーションの設定を保存、復元する方法には、実に様々な方法 があり、ここで紹介した以外にもまだまだあるでしょう。ここで紹介 した方法よりもよい方法をご存知の方は、ご連絡いただければ幸いで す。 参考: [URL].NET Framework におけるアプリケーション設定の永続化 http://www.microsoft.com/japan/msdn/net/general/persistappsettnet.asp =============================== ■このマガジンの購読、購読中止、バックナンバー、説明に関しては  次のページをご覧ください。  http://www.mag2.com/m/0000104516.htm ■発行人・編集人:どぼん!  (Microsoft MVP for Visual Basic, Oct 2003-Oct 2004)  http://dobon.net  dobon_info@yahoo.co.jp ■ご質問等はメールではなく、掲示板へお願いいたします。  http://dobon.net/vb/bbs.html ■上記メールアドレスへのメールは確実に読まれる保障はありません  (スパム、ウィルス対策です)。メールは下記URLのフォームメール  から送信してください。  http://dobon.net/mail.html Copyright (c) 2003 - 2004 DOBON! All rights reserved. ===============================