delete from hateblo.jp where 1=1;

タイトルに意味はありません。

user.configが崩壊

対象

  • ApplicationSettingsを使用している
  • 突然のException on System.Configuration

原因

アプリケーションの不正終了や、不正セクタのせいで、%LocalAppData%\CompanyName\Assembly_Url_sha256\user.configが崩壊する。

対策

Application.Run()前に、CheckConfiguration()をコールする。
formのコンストラクタで処理をさせてもよさげ。

.net - C# - User Settings broken - Stack Overflow (英語)

以下の宣言は忘れずに。参照設定へSystem.Configurationの追加を忘れずに。

using System.Configuration;
using System.IO;
using System.Threading;

コードは以下の通り。

        /// <summary>
        /// 設定を確認する
        /// </summary>
        /// <exception cref="UnauthorizedAccessException">呼び出し元に、必要なアクセス許可がありません。またはpath がディレクトリです。またはpath によって、読み取り専用のファイルが指定されました。</exception>
        /// <returns>true:設定ファイルが削除された/false:通常</returns>
        static public bool CheckConfiguration()
        {
            try
            {
                ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.PerUserRoamingAndLocal);
                return false;
            }
            catch (ConfigurationErrorsException ex)
            {
                var filename = ex.Filename;
                if (string.IsNullOrEmpty(filename))
                    filename = (ex.InnerException as ConfigurationErrorsException)?.Filename;
                return DeleteWait(filename, 10);
            }
        }
        /// <summary>
        /// ファイルが削除するまで待機する
        /// </summary>
        /// <param name="filename">ファイル名</param>
        /// <param name="retry">リトライ回数</param>
        /// <exception cref="UnauthorizedAccessException">呼び出し元に、必要なアクセス許可がありません。またはpath がディレクトリです。またはpath によって、読み取り専用のファイルが指定されました。</exception>
        /// <returns>削除有無</returns>
        static bool DeleteWait(string filename, int retry)
        {
            if (string.IsNullOrEmpty(filename) || !File.Exists(filename))
                return false;
            for (var i = 0; i < retry; i++)
            {
                try
                {
                    if (File.Exists(filename))
                        File.Delete(filename);
                    using (var watcher = new FileSystemWatcher(Path.GetDirectoryName(filename), Path.GetFileName(filename)))
                    {
                        if (File.Exists(filename))
                            watcher.WaitForChanged(WatcherChangeTypes.Deleted);
                    }
                    return true;
                }
                catch (IOException) { }
                Thread.Sleep(1000);
            }
            return false;
        }

参考文献