C#でユーザーの設定内容を保存する

環境：Windows7以上であれば、インストール不要で使えます。
・Windows10
・コンパイラ `C:\Windows\Microsoft.NET\Framework64\v4.0.30319\csc.exe`

# やれること
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/438183/2317f218-5f68-3a52-8ed5-e0b5077ee66b.png)
のテキストを編集して、ウィンドウを閉じると、次回起動時に、編集されたテキストをロードできる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/438183/9599c1a7-1923-548e-78aa-279be71cabea.png)


# ソースコード

このサンプルコードでは、起動時に読み込んで、閉じられるときに保存しているが、
ボタンなどのユーザー操作起点で読み込み・保存させることも可能。（参考サイト参照）

```csharp:UserTest.cs

using System;
using System.Windows.Forms;
using System.Configuration;


namespace Kob58im
{
    public class MySetting : ApplicationSettingsBase
    {
        [UserScopedSetting()]
        [DefaultSettingValue("hoge")]
        public string Message
        {
            get { return (string)this["Message"]; }
            set { this["Message"] = value; }
        }
    }


    class UserTestClass : Form
    {
        TextBox txt;
        MySetting appSettings;

        UserTestClass()
        {
            appSettings = new MySetting();

            txt = new TextBox();
            Controls.Add(txt);

            LoadSettings();
            Closing += (sender,e)=>{SaveSettings();};
        }

        void LoadSettings()
        {
            txt.Text = (string)appSettings.Message;
        }

        void SaveSettings()
        {
            appSettings.Message = txt.Text;
            appSettings.Save();
        }

        [STAThread]
        static void Main()
        {
            Application.Run(new UserTestClass());

            // どこに設定ファイルが保存されたかを出力
            Console.WriteLine("Configuration path:");
            Configuration config =
                ConfigurationManager.OpenExeConfiguration(
                ConfigurationUserLevel.PerUserRoamingAndLocal);
            Console.WriteLine(config.FilePath);

        }
    }
}

```

# 設定ファイルはどこに保存されるか？

`C:\Users\`【ユーザー名】`\AppData\Local\Kob58im\UserTest.exe_Url_`xxxxxxxxxxxx`\0.0.0.0\user.config`

に保存された。下記のような感じ。

- `%LOCALAPPDATA%`の直下に、名前空間のフォルダができる。
- exe名が付く。
- 謎のIDが付く(32文字の英数？)。[何かのハッシュのよう。](https://dobon.net/vb/dotnet/programing/mysettings.html#scope)
- exeのバージョンが付く。[バージョンはapp.manifestで設定できそう。](https://qiita.com/kob58im/items/9539ab61cc09b67f7c50#%E3%82%B3%E3%83%B3%E3%83%91%E3%82%A4%E3%83%AB%E6%99%82%E3%81%AE%E8%A8%AD%E5%AE%9A%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB)


# 保存されたファイルの中身

```xml:user.config

<?xml version="1.0" encoding="utf-8"?>
<configuration>
    <configSections>
        <sectionGroup name="userSettings" type="System.Configuration.UserSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=XXXXXXXXXXXXXXXX" >
            <section name="Kob58im.MySetting" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=XXXXXXXXXXXXXXXX" allowExeDefinition="MachineToLocalUser" requirePermission="false" />
        </sectionGroup>
    </configSections>
    <userSettings>
        <Kob58im.MySetting>
            <setting name="Message" serializeAs="String">
                <value>hogePiyo</value>
            </setting>
        </Kob58im.MySetting>
    </userSettings>
</configuration>

```

- 名前空間を含むクラス名`Kob58im.MySetting`が含まれており、設定用のクラス毎にバッティングしないようになっている。
- .Netの提供してくれるクラス`System.Configuration.ClientSettingsSection`のバージョン`4.0.0.0`が含まれている。（.Netの環境を変えるとデータの読み書きができない可能性あり。）

# 参考サイト

下記がかなり詳しい。
https://dobon.net/vb/dotnet/programing/applicationsettingsbase.html

# 参考サイト - iniファイルを読む込む方法

iniファイルはあまり推奨されていない気がしますが、ユーザーが編集するならxmlよりiniのほうが楽かなということで紹介。

文字コードも考慮されています。
http://tech.hikware.com/article/20170817a.html