◆ App.config の読み取りはカレントディレクトリじゃなくてアセンブリのあるフォルダみたい
◆ exe ファイルへのシンボリックリンクをコマンドプロンプト (batファイル) から起動するときは注意
  ◆ シンボリックリンクフォルダの App.config を読みとろうとするのでファイルがないと読み取れない

準備


[App.config]
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <startup>
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6" />
    </startup>

  <appSettings>
    <add key="abc" value="def" />
  </appSettings>
</configuration>

[MainWindow.xaml.cs]
public MainWindow()
{
var val = System.Configuration.ConfigurationManager.AppSettings["abc"];
MessageBox.Show($"val : {val ?? "null"}");

InitializeComponent();
}

こういうコードで ビルド後に exe ファイルへシンボリックリンクを設定します

フォルダ構成


ビルドしたファイル
    C:\data\test.exe
    C:\data\test.exe.config

シンボリックリンク
    C:\sym\link.exe ===> C:\data\test.exe

実行

test.exe をクリックして実行した場合は 「val: def」 と App.config の中身が読み取れます
link.exe をクリックした場合も 「val: def」 とちゃんと読み取れます

ですが link.exe をコマンドプロンプトから実行すると 「val: null」 になります

○ test.exe をクリック
○ test.exe をコマンドプロンプトで実行
○ test.exe を別フォルダをカレントディレクトリにしてコマンドプロンプトで実行
○ test.exe を bat ファイルから実行
○ link.exe をクリック

は大丈夫なのに link.exe をコマンドプロンプトから実行したときだけ読み取れません


考えてみると App.config の読み取りは exe ファイル名 + .config なのでカレントディレクトリ変わったらダメそうなのに読み取れています

シンボリックリンクをコマンドプロンプトから実行した場合だけ値が変わって実行ファイルの場所を見るものと言えば……

この記事で書いたアセンブリのディレクトリ

シンボリックリンクをコマンドプロンプトから実行した場合だけシンボリックリンクのあるフォルダ それ以外は exe ファイルのあるフォルダになっていました

この方法で取れるパスを使っているのだと考えるとこういう動きなのもなっとくできます


C:\sym\link.exe.config を作って
<add key="abc" value="ghi" />
にすると 「val: ghi」 と表示されました

この場合の実行ファイルは C:\sym\link.exe になっているので C:\sym\test.exe.config ではなく C:\sym\link.exe.config にしないといけません

シンボリックリンク用にファイル準備するのはちょっと面倒
でもやらないとたまたまコマンドプロンプトから実行したらなんか動かない ってなるしやるしかなさそう
コマンドプロンプトからの起動でダメってことは bat ファイルからの起動もダメだし


C# からの外部プログラム起動ではシンボリックリンクを指定しても test.exe を直接起動するのと同じのようで 「val: def」 が表示されました
Process.Start(@"C:\Data\Programs\sym.exe");


これ絶対罠だよね