none
Windowsフォームアプリにおけるアプリケーション設定の実装について RRS feed

  • 質問

  • ■知りたいこと

    以下で説明する「やりたいこと」について、色々と手段はあると思いますが、どのような方法が現時点で最も推奨されるのかを知りたいです。

    ※やりたいことについて検索すると、様々なやり方が大量に出てくるので、逆に悩ましい。より後で提案された手法が推奨されるものだと思うのですが、それが何かわかりません。

    ■環境

    • Windows7 Professional または Windows10 Professional/Enterprise/Enterprise LTSB(2016) 英語版 32bit/64bit
    • .NET Framework 4.6.0
    • Visual Studio 2017 Professional 日本語版
    • C# Windowsフォームアプリケーション(古典的なデスクトップアプリケーションです)

    ■やりたいこと

    アプリケーションの設定を永続化したい。この設定はユーザー毎のものであり、ローミング有りのため%APPDATA%の下にファイルとして保存されることを想定しています。その際追加で以下の要件があります:

    • 想定としては%APPDATA%の下に「会社名/アプリケーション名」というフォルダが掘られ、その中に設定ファイルが保存されるものと考えているが、必ずしもその通りでなくてもよい。何か一般的なルールがMicrosoftから提示されているなら、それに従いたい。
    • ただし%APPDATA%の下のフォルダにアプリケーションのバージョン番号は含めたくない。バージョンアップ毎に設定ファイルが変わったりフォルダが掘られることは避けたいので。
    • プロセスの初回起動時(設定が空)は、アプリケーションの本来の処理を開始する前(メインのフォームを出す等の前)に自作の設定フォームを表示し、設定させる。2回目起動以降も、ユーザーが設定を閲覧し、必要に応じて書き換えすることが想定される。

    ■質問詳細

    1. C#プロジェクトのプロパティをVisual Studio上で開いて「設定」の項目を選ぶと、アプリケーション設定を追加できますが、これの永続化ファイルをインストールフォルダ(C:\Program Files\の下のアプリケーションインストールフォルダ)ではなく%APPDATA%の下に配置することは可能なのかどうか。
    2. System.Windows.Forms.Application.UserAppDataPathにはアプリケーションのバージョン番号が含まれてしまうが、それを回避する手段はあるのかどうか。
    3. 結局のところ、現時点で推奨される手段で標準的なもの(.NET Frameworkで提供されるクラスや、VisualStudioプロジェクトに紐づく何か)はあるのか。それとも、System.XMLなどを駆使して自前で実装したほうがよいのか。

    2018年3月19日 7:50

すべての返信

  • Visual Studioが標準で提供している、.NETベースのデスクトップアプリケーション設定の管理機能では、アプリケーションスコープおよびユーザースコープという2種類の設定を管理できます。アプリケーションスコープ設定(およびユーザースコープ設定の既定値)は、EXEのあるフォルダーに<AppName>.exe.configという名前で作成されるXMLによって管理されますが、これはエンドユーザーが自由に変更可能な設定内容を管理するものではありません。一方、ユーザースコープ設定に関しては、既定で以下の場所にXMLファイルが保存されます。

    %LocalAppData%/<CompanyName>/<AppName>_Url_<RandomString>/<VersionNumber>/user.config

    アプリケーションの設定の管理 (.NET) - MSDN

    Visual Studioでアプリケーションの設定を保存する - .NET Tips (VB.NET,C#...)

    ユーザースコープ設定ファイルの保存場所を、既定の場所から任意の場所に変更するのは少々面倒です。詳しくは上記リンク先を参照してください。

    上記のVisual Studio標準機能を使った設定管理は、設定項目をプロパティとして扱えるラッパークラスが自動生成されて便利ですが、自由な制御は難しくなります。

    個人的にオブジェクトのシリアライズ/逆シリアライズによく使っているのは、XmlSerializerを使う方法です。直接シリアライズ/逆シリアライズすることができない型が存在するなどの制約はありますが、最もシンプルです。設定ファイルのフォーマットにXMLを使いたくない場合は、BinaryFormatterを使う方法もあります。

    ISerializableを使うと、シリアライズ/逆シリアライズの処理をカスタマイズすることができます。また、DataContractSerializerを使うと、XmlSerializerよりも細やかで柔軟な制御ができるようになります。

    いずれにせよ、ローミング対応するためには自前で対処する必要があります。

    どの方法を採用するのがベストなのかは結局のところ、シリアライズ/逆シリアライズする設定内容およびアプリケーションの性質や規模にもよるので、自分で実際に試してみて決めたほうがいいと思います。細やかな制御をしたければ、当然開発工数が増大するというトレードオフになります。場合によっては、XMLを使うよりもJSONなどのデータ記述言語の処理系を組み込んだほうがよいこともあります。

    推奨手法や非推奨手法などというものはありませんが、少なくともオブジェクトのシリアライズ/逆シリアライズ目的では、今どきローレベルなSAX/DOMを直接使う必要はありません。

    • 編集済み sygh 2018年3月19日 17:13
    2018年3月19日 15:09