DOBON.NET DOBON.NETプログラミング掲示板過去ログ

Properties.Settings.Default.Save()で保存されない

環境/言語:[Windows XP C# .NET 4.0]
分類:[.NET]

下記のページを見て、アプリケーションの設定を勉強しています。

http://dobon.net/vb/dotnet/programing/mysettings.html

プロジェクトのプロパティで、設定を行いました。

名前:GETTEXT
型:String
スコープ:ユーザー
値 Hi

Form上のボタンをクリックすると保存するコードを書きました。
「保存しました。」というメッセージは表示されますが、プロパティの「Hi」は「hello」に変わっていません。
何が原因でしょうか?PCの再起動などはおこなったのですが、何もおきず・・・

private void cmdSave_Click(object sender, EventArgs e)
{
//保存
Properties.Settings.Default.GETTEXT = "hello";
Properties.Settings.Default.Save();
MessageBox.Show("保存しました。");
}

以上、よろしくお願いします。
■No32104に返信(omniさんの記事)
> プロパティの「Hi」は「hello」に変わっていません。

Properties.Settings.Default.GETTEXT = "hello";
Properties.Settings.Default.Save();
Console.WriteLine( Properties.Settings.Default.GETTEXT );

が「Hi」と表示される、ということでしょうか。だとしたら、
保存後に Properties.Settings.Default.Reload(); を行った後、あるいは
保存後に Properties.Settings.Default.Reset(); を行った後に実行すると、
それぞれ何が表示されますか?


あるいは user.config ファイルの内容が書き換わらない、という意味でしょうか?
その場合、どこに置かれているファイルの内容を確認されていますか?
魔界の仮面弁士さん

ご回答ありがとうございます。ファイルの内容が書き換わらないというのは、
下記の画面の、「値」のところが書き換わりません。つまり、「Hi」のままです。

http://dobon.net/vb/dotnet/programing/img/storeappsettings1.png

また、「app.config」の中身の値も変更がありません。
プログラムを実行した後も、前も、

<setting name="GETTEXT" serializeAs="String">
<value>Hi</value>
</setting>

上記の値のままです。

「app.config」は下記のパスに存在します。
「C:\Documents and Settings\MYPCC\My Documents\Visual Studio 2010\Projects\test\test\app.config」

Reload、ResetをSave後に実行した結果は下記になります。
よろしくお願いします。

コード:
Properties.Settings.Default.GETTEXT = "hello";
Console.WriteLine("test test test");
Console.WriteLine(Properties.Settings.Default.GETTEXT);

出力結果:
test test test
ステップ イン: プロパティ 'TEST.Properties.Settings.Default.get' をステップ オーバーしています。プロパティにステップ インするには、[ツール] メニューの [オプション] をクリックし、[デバッグ] をクリックしてから、[プロパティおよび演算子をステップ オーバーする (マネージのみ)] チェック ボックスをオフにしてください。
ステップ イン: プロパティ 'TEST.Properties.Settings.GETTEXT.get' をステップ オーバーしています。プロパティにステップ インするには、[ツール] メニューの [オプション] をクリックし、[デバッグ] をクリックしてから、[プロパティおよび演算子をステップ オーバーする (マネージのみ)] チェック ボックスをオフにしてください。
ステップ イン: 非ユーザー コード 'System.Console.Out.get' をステップ オーバーしています
hello

Reloadを行なった場合のコード:
Properties.Settings.Default.GETTEXT = "hello";
Console.WriteLine("test test test");
Console.WriteLine(Properties.Settings.Default.GETTEXT);
Properties.Settings.Default.Save();
Properties.Settings.Default.Reload();
MessageBox.Show("保存しました。");

出力結果: 書き換えされていませんでした。
test test test
hello
ステップ イン: プロパティ 'TEST.Properties.Settings.Default.get' をステップ オーバーしています。プロパティにステップ インするには、[ツール] メニューの [オプション] をクリックし、[デバッグ] をクリックしてから、[プロパティおよび演算子をステップ オーバーする (マネージのみ)] チェック ボックスをオフにしてください。
ステップ イン: 非ユーザー コード 'System.Configuration.ApplicationSettingsBase.Save' をステップ オーバーしています
ステップ イン: プロパティ 'TEST.Properties.Settings.Default.get' をステップ オーバーしています。プロパティにステップ インするには、[ツール] メニューの [オプション] をクリックし、[デバッグ] をクリックしてから、[プロパティおよび演算子をステップ オーバーする (マネージのみ)] チェック ボックスをオフにしてください。
ステップ イン: 非ユーザー コード 'System.Configuration.ApplicationSettingsBase.Reload' をステップ オーバーしています
ステップ イン: プロパティ 'TEST.Properties.Settings.MyLocation.get' をステップ オーバーしています。プロパティにステップ インするには、[ツール] メニューの [オプション] をクリックし、[デバッグ] をクリックしてから、[プロパティおよび演算子をステップ オーバーする (マネージのみ)] チェック ボックスをオフにしてください。
ステップ イン: 非ユーザー コード 'System.ComponentModel.ReflectPropertyDescriptor.GetValue' をステップ オーバーしています
ステップ イン: 非ユーザー コード 'System.Windows.Forms.BindToObject.GetValue' をステップ オーバーしています
ステップ イン: 非ユーザー コード 'System.Windows.Forms.Binding.PushData' をステップ オーバーしています
ステップ イン: 非ユーザー コード 'System.Windows.Forms.BindingManagerBase.PushData' をステップ オーバーしています
ステップ イン: 非ユーザー コード 'System.Windows.Forms.PropertyManager.OnCurrentChanged' をステップ オーバーしています
ステップ イン: 非ユーザー コード 'System.Configuration.ApplicationSettingsBase.Reload' をステップ オーバーしています
ステップ イン: 非ユーザー コード 'System.Windows.Forms.MessageBox.Show' をステップ オーバーしています

Resetを行なった場合のコード:
Properties.Settings.Default.GETTEXT = "hello";
Console.WriteLine("test test test");
Console.WriteLine(Properties.Settings.Default.GETTEXT);
Properties.Settings.Default.Save();
Properties.Settings.Default.Reset();
MessageBox.Show("保存しました。");

出力結果: 書き換えされていませんでした。
test test test
hello
ステップ イン: プロパティ 'TEST.Properties.Settings.Default.get' をステップ オーバーしています。プロパティにステップ インするには、[ツール] メニューの [オプション] をクリックし、[デバッグ] をクリックしてから、[プロパティおよび演算子をステップ オーバーする (マネージのみ)] チェック ボックスをオフにしてください。
ステップ イン: 非ユーザー コード 'System.Configuration.ApplicationSettingsBase.Save' をステップ オーバーしています
ステップ イン: プロパティ 'TEST.Properties.Settings.Default.get' をステップ オーバーしています。プロパティにステップ インするには、[ツール] メニューの [オプション] をクリックし、[デバッグ] をクリックしてから、[プロパティおよび演算子をステップ オーバーする (マネージのみ)] チェック ボックスをオフにしてください。
ステップ イン: 非ユーザー コード 'System.Configuration.ApplicationSettingsBase.Reset' をステップ オーバーしています
ステップ イン: プロパティ 'TEST.Properties.Settings.MyLocation.get' をステップ オーバーしています。プロパティにステップ インするには、[ツール] メニューの [オプション] をクリックし、[デバッグ] をクリックしてから、[プロパティおよび演算子をステップ オーバーする (マネージのみ)] チェック ボックスをオフにしてください。
ステップ イン: 非ユーザー コード 'System.ComponentModel.ReflectPropertyDescriptor.GetValue' をステップ オーバーしています
ステップ イン: 非ユーザー コード 'System.Windows.Forms.BindToObject.GetValue' をステップ オーバーしています
ステップ イン: 非ユーザー コード 'System.Windows.Forms.Binding.PushData' をステップ オーバーしています
ステップ イン: 非ユーザー コード 'System.Windows.Forms.BindingManagerBase.PushData' をステップ オーバーしています
ステップ イン: 非ユーザー コード 'System.Windows.Forms.PropertyManager.OnCurrentChanged' をステップ オーバーしています
ステップ イン: 非ユーザー コード 'System.Configuration.ApplicationSettingsBase.Reload' をステップ オーバーしています

>
> Properties.Settings.Default.GETTEXT = "hello";
> Properties.Settings.Default.Save();
> Console.WriteLine( Properties.Settings.Default.GETTEXT );
>
> が「Hi」と表示される、ということでしょうか。だとしたら、
> 保存後に Properties.Settings.Default.Reload(); を行った後、あるいは
> 保存後に Properties.Settings.Default.Reset(); を行った後に実行すると、
> それぞれ何が表示されますか?
>
>
> あるいは user.config ファイルの内容が書き換わらない、という意味でしょうか?
> その場合、どこに置かれているファイルの内容を確認されていますか?
2014/01/24(Fri) 23:03:42 編集(投稿者)

■No32106に返信(omniさんの記事)
> 下記の画面の、「値」のところが書き換わりません。

Save しても app.config や appName.exe.config が変更されることはありません。
ユーザー設定の保存先は別のファイルです。

なお、実行環境に .config ファイルを配置していなかった場合、
Properties.Settings.Default は、開発時に設定された値を初期値として返します。


> 出力結果:
> test test test
> hello

もしも 設定情報(≠app.config)が書き換わっていないのであれば、
上記は「hello」ではなく、「hi」と出力されていたはずですよね。

Save 後にアプリを起動しなおしてみて、その後、GETTEXT を修正せずに、
 Console.WriteLine(Properties.Settings.Default.GETTEXT);
を実行してみてください。それが「hi」なら Save できていないことになりますし、
「hello」になっていれば、Save できていることになります。



>> あるいは user.config ファイルの内容が書き換わらない、という意味でしょうか?
>>その場合、どこに置かれているファイルの内容を確認されていますか?
> また、「app.config」の中身の値も変更がありません。

「app.config」ではなく
「user.config」を見てください。


> 「C:\Documents and Settings\MYPCC\My Documents\Visual Studio 2010\Projects\test\test\app.config」
これは Windows XP でしょうか? MYPCC というユーザー名なのですね。


(1)開発時には、app.config を整備するところからはじめますよね。これは設定ファイルのテンプレートです。

(2)コンパイルすると、アセンブリの名前 ( yourAppName.exe )に合わせて、同じ場所に yourAppName.exe.config が作られます。内容は app.config と同じ内容ですが、実際に使われるのは yourAppName.exe.config の方です。

(3)これらの .config は、基本的に ReadOnly として扱われます。何故ならば、実行ユーザーは、配置先(Program Files フォルダーなど)への書き込み権限を有していない可能性が高いからです。全ユーザーで共通して使われる『アプリケーション スコープ』や ConnectionString といった項目が ReadOnly なのもそのためです。

(4)『ユーザー スコープ』の設定であれば実行時に編集できますが、この値は yourAppName.exe.config そのものに対してではなく、別の場所にある「user.config」に保存されるようになっています。これはユーザー別のフォルダーに配置されるため、書き込み権限を気にする必要がありません。ただしユーザー別に管理されるため、アプリケーション単位の設定(ユーザー間で共有されるような情報)を保存する目的には使えません。


user.config の具体的なパスを知りたい場合は、下記のコードを実行してみてください。
Windows XP であれば、「C:\Documents and Settings\MYPCC\Application Data\〜〜\user.config」のようなパスになると思います。

// 参照設定に System.Configuration.DLL を加える必要があります。
string 構成ファイルの場所 = System.Configuration.ConfigurationManager.OpenExeConfiguration(System.Configuration.ConfigurationUserLevel.PerUserRoaming).FilePath;
下記のフォルダに、appName.exe.config、app.configがありました。これらのファイルに変更が無かったことは確認しました。

app.config:
C:\Documents and Settings\MYPCC\My Documents\Visual Studio 2010\Projects\test\test

appName.exe.config
C:\Documents and Settings\MYPCC\My Documents\Visual Studio 2010\Projects\test\test\bin\Debug

>Save 後にアプリを起動しなおしてみて、その後、GETTEXT を修正せずに、
>Console.WriteLine(Properties.Settings.Default.GETTEXT);
>を実行してみてください。それが「hi」なら Save できていないことになりますし、
>「hello」になっていれば、Save できていることになります。

user.configは下記のフォルダにありました。
C:\Documents and Settings\MYPCC\Local Settings\Application Data\COMPUTER_NAME\test.exe_Url_英数字の羅列v0\1.0.0.0

その中で、データは変更されていることを確認しました。

てっきり、app.configに書込がされると勘違いしていましたが、お教え頂きましたapp.configは設定ファイルのテンプレートというのは理解していませんでした。

謎が解決しました。本当にありがとうございます。

■No32107に返信(魔界の仮面弁士さんの記事)
> 2014/01/24(Fri) 23:03:42 編集(投稿者)
>
> ■No32106に返信(omniさんの記事)
>>下記の画面の、「値」のところが書き換わりません。
>
> Save しても app.config や appName.exe.config が変更されることはありません。
> ユーザー設定の保存先は別のファイルです。
>
> なお、実行環境に .config ファイルを配置していなかった場合、
> Properties.Settings.Default は、開発時に設定された値を初期値として返します。
>
>
>>出力結果:
>>test test test
>>hello
>
> もしも 設定情報(≠app.config)が書き換わっていないのであれば、
> 上記は「hello」ではなく、「hi」と出力されていたはずですよね。
>
> Save 後にアプリを起動しなおしてみて、その後、GETTEXT を修正せずに、
>  Console.WriteLine(Properties.Settings.Default.GETTEXT);
> を実行してみてください。それが「hi」なら Save できていないことになりますし、
> 「hello」になっていれば、Save できていることになります。
>
>
>
> >> あるいは user.config ファイルの内容が書き換わらない、という意味でしょうか?
> >>その場合、どこに置かれているファイルの内容を確認されていますか?
>>また、「app.config」の中身の値も変更がありません。
>
> 「app.config」ではなく
> 「user.config」を見てください。
>
>
>>「C:\Documents and Settings\MYPCC\My Documents\Visual Studio 2010\Projects\test\test\app.config」
> これは Windows XP でしょうか? MYPCC というユーザー名なのですね。
>
>
> (1)開発時には、app.config を整備するところからはじめますよね。これは設定ファイルのテンプレートです。
>
> (2)コンパイルすると、アセンブリの名前 ( yourAppName.exe )に合わせて、同じ場所に yourAppName.exe.config が作られます。内容は app.config と同じ内容ですが、実際に使われるのは yourAppName.exe.config の方です。
>
> (3)これらの .config は、基本的に ReadOnly として扱われます。何故ならば、実行ユーザーは、配置先(Program Files フォルダーなど)への書き込み権限を有していない可能性が高いからです。全ユーザーで共通して使われる『アプリケーション スコープ』や ConnectionString といった項目が ReadOnly なのもそのためです。
>
> (4)『ユーザー スコープ』の設定であれば実行時に編集できますが、この値は yourAppName.exe.config そのものに対してではなく、別の場所にある「user.config」に保存されるようになっています。これはユーザー別のフォルダーに配置されるため、書き込み権限を気にする必要がありません。ただしユーザー別に管理されるため、アプリケーション単位の設定(ユーザー間で共有されるような情報)を保存する目的には使えません。
>
>
> user.config の具体的なパスを知りたい場合は、下記のコードを実行してみてください。
> Windows XP であれば、「C:\Documents and Settings\MYPCC\Application Data\〜〜\user.config」のようなパスになると思います。
>
> // 参照設定に System.Configuration.DLL を加える必要があります。
> string 構成ファイルの場所 = System.Configuration.ConfigurationManager.OpenExeConfiguration(System.Configuration.ConfigurationUserLevel.PerUserRoaming).FilePath;
解決済み!

DOBON.NET | プログラミング道 | プログラミング掲示板