M12i.

学術書・マンガ・アニメ・映画の消費活動とプログラミングについて

ショートファイル名で実行された場合でも*.exe.configを読み込む

前回の記事で紹介したように、Windows OSの環境で.NET Frameworkアプリケーションを実行するとき、エントリーポイントとなったアセンブリの名称がショートファイル名(8.3形式)で認識されるケースがあります。

この場合、アプリケーション構成ファイル *.exe.config は読み込まれず、ConfigurationManager.AppSettingsConfigurationManager.ConnectionStringsが返すコレクションは要素を含まない空のコレクションになってしまいます。

問題への対策にはConfigurationManager.OpenMappedExeConfiguration(...)メソッドを利用します:

string mayShortName = Assembly.GetEntryAssembly().Location;
string longName = Path.GetFullPath(mayShortName);
ExeConfigurationFileMap fileMap = new ExeConfigurationFileMap
{
	ExeConfigFilename = longName  + ".config"
};
Configuration conf = ConfigurationManager.OpenMappedExeConfiguration
                    (fileMap, ConfigurationUserLevel.None);

このコードはPath.GetFullPath(...)メソッドがショートファイル名のパスをロングファイル名のパスに変換してくれるのを利用して、アプリケーション構成ファイルのパスを導出して読み込みを行います。

アプリケーション構成ファイルのロードには上位のファイルからの継承やローミングの有無など複雑な決まりごとがあるようで、それらすべてを考えた場合にこれが完全な対案となっているかどうかはわかりませんが・・・。

しかしAppSettingsプロパティなどが返すNameValueCollectionと異なり、このメソッドが返すのはConfigurationです。明らかに使い勝手が悪いです。ここからIDictionary<string, string>形式で設定情報を引き出すには次のようなコードを書くことになるでしょう:

IDictionary<string,string> appSettings = conf.AppSettings.Settings
                .Cast<KeyValueConfigurationElement>()
                .ToDictionary(e => e.Key, e => e.Value);
IDictionary<string,string> connStrings = conf.ConnectionStrings.ConnectionStrings
                .Cast<ConnectionStringSettings>()
                .ToDictionary(s => s.Name, s => s.ConnectionString);

やたらと手間がかかりますが、とにかくこれでアプリケーションがショートファイル名で実行された場合でも*.exe.configを読み込むことができます。