exe ファイルと同じ場所にフォルダを作成して、この中に dll ファイルをまとめて配置しておいて読み込みたい

フォルダ構成の見通しは大事だよね。

目次

System.IO.FileNotFoundException は見ていた

exe と dll は同じフォルダに置いておかないと、見つからないよエラーが発生してしまいます。

アプリケーションのコンポーネントで、ハンドルされていない例外が発生しました。
[続行] をクリックすると、アプリケーションはこのエラーを無視し、続行しようとします。
[終了] をクリックすると、アプリケーションは直ちに終了します。

ファイルまたはアセンブリ 'ClassLibrary1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' 、またはその依存関係の1つが読み込めませんでした。
指定されたファイルが見つかりません。

現象再現

例えば、Windows フォーム アプリケーションクラスライブラリの2つのプロジェクトがあったとして、Windows フォーム アプリケーション側が参照設定でクラスライブラリを参照している場合です。

クラスライブラリ

Public Class Class1

    Public Sub ShowMessage(msg As String)
        Console.WriteLine(msg)
    End Sub

End Class

Windows フォーム アプリケーション

参照設定より、ClassLibrary1 を追加しておきます。

Public Class Form1

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click

        Dim c1 As New ClassLibrary1.Class1
        c1.ShowMessage("hello")

    End Sub

End Class

ビルドした後、bin/Debug フォルダを開いて、ClassLibrary1.dll を削除、またはリネームするか、フォルダを作成してこの中に WindowsApplication1.exe を入れておきます。後は、exe ファイルを実行してボタンを押すとエラーが発生します。

コンフィグファイルに、探す場所を書いて教えておこう!

で、どうすればいいのかというと、コンフィグファイル(WindowsApplication1.exe.config など)にフォルダ名を記載しておくといいです。Visual Studio にD&Dしてもいいし、App.config を書き換えても良いです。

初期構成

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <startup>
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
    </startup>
</configuration>

記載後

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <startup>
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
    </startup>

    <!-- ここから -->
    <runtime>
        <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
            <probing privatePath="app" />
        </assemblyBinding>
    </runtime>
  <!-- ここまで -->
  
</configuration>

実行

これでいけるはずです。複数フォルダの指定やサブフォルダにも対応していて、こういう風に書きます。

<probing privatePath="app;app2;app3\subapp" />