2018年12月2日日曜日

C# Properties.Settings user.configの破損による例外発生への対応

Properties.Settingsを使用したアプリケーション設定を利用していますが、これが保存されるuser.configが何故か壊れ、次の例外が発生するようになりました。

 System.Configuration.ConfigurationErrorsException
 構成システムを初期化できませんでした。

たぶんデバッグ中にuser.configが正常に保存されなかったためだと思いますが、この状態になるとなんとも困ったことになります。

user.configはxmlファイルですが、これが破損するとロード時にエラーが発生します。その結果、Properties.Settings.Defaultのプロパティーに適切な値が設定されず、get/setいずれでもエラーが発生するようになってしまいます。

いろいろ試したところでは、Properties.Settings.Defaultオブジェクトは一度だけ作られ、Reloadしても作り直されません。私の結論としては、user.configを削除しアプリを再起動するしか回復の方法がありません。

user.configを削除してアプリを再起動すれば、設定は初期状態になるものの、例外は発生しなくなります。

user.configは通常は次の場所にあるでしょう。
C:\Users\UserName\AppData\Local\AppName\AppName.exe_Url_HashValue

このフォルダの場所はOSバージョンやインストールの仕方で異なる可能性があり、ハッシュ値はアプリのバージョンにより異なること可能性があります。また、開発環境ではビルドによっても異なるハッシュ値が作られることがあります。

この問題への対処方法が次のWebページにありました。

Properties.Settings.Defaultへのアクセスで例外が発生したときに、そのInnerExceptionのFileNameを使い、user.configを削除しています。

このWebページでは削除後に Settings.Default.Reload(); を呼んでいますが、どうやらReloadはすでに読み込んだxmlから値を元に戻すようで、Settings.Defaultのプロパティーのエラー状態は回復しません。Reloadではうまくいかないことはこのページのコメントにも書かれています。

そこで、次のような要領で、エラーが発生したらuser.configを削除し、アプリを再起動するようにしました。

try
{
String val = Properties.Settings.Default.someStringProperty;
}
catch (Exception ex)
{
 //MessageBox.Show("設定ファイルが破損しています。...");
string filePath = ((ConfigurationErrorsException)ex.InnerException).Filename;
File.Delete(filePath);
 Application.Restart();
}

VisualStudioでConfigurationErrorsExceptionが見つからない場合は、プロジェクトの参照にSystem.Configurationを追加します。