web-dev-qa-db-ja.com

/ binディレクトリ内からすべてのアセンブリをロードする方法

Webアプリケーションで、/ binディレクトリのすべてのアセンブリをロードしたい。

これはファイルシステムの任意の場所にインストールできるため、保存先の特定のパスを保証することはできません。

アセンブリアセンブリオブジェクトのList <>が必要です。

39
mrblah

さて、次の方法でこれを自分で一緒にハックできます。最初は次のようなものを使用します:

string path = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);

現在のアセンブリへのパスを取得します。次に、適切なフィルターを使用してDirectory.GetFilesメソッドを使用して、パス内のすべてのDLLを反復処理します。最終的なコードは次のようになります。

List<Assembly> allAssemblies = new List<Assembly>();
string path = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);

foreach (string dll in Directory.GetFiles(path, "*.dll"))
    allAssemblies.Add(Assembly.LoadFile(dll));

私はこれをテストしていないことに注意してください。dllが実際にフルパスを含むことを確認する必要があるかもしれません(そうでない場合はパスを連結します)

45
Wolfwyrd

Binディレクトリを取得するには、string path = Assembly.GetExecutingAssembly().Location;[〜#〜] not [〜#〜]常に動作します(特に、実行中のアセンブリがASP.NET一時ディレクトリに配置されている場合) )。

代わりに、string binPath = System.IO.Path.Combine(System.AppDomain.CurrentDomain.BaseDirectory, "bin");を使用する必要があります

さらに、おそらくFileLoadExceptionとBadImageFormatExceptionを考慮する必要があります。

私の機能は次のとおりです。

public static void LoadAllBinDirectoryAssemblies()
{
    string binPath = System.IO.Path.Combine(System.AppDomain.CurrentDomain.BaseDirectory, "bin"); // note: don't use CurrentEntryAssembly or anything like that.

    foreach (string dll in Directory.GetFiles(binPath, "*.dll", SearchOption.AllDirectories))
    {
    try
    {                    
        Assembly loadedAssembly = Assembly.LoadFile(dll);
    }
    catch (FileLoadException loadEx)
    { } // The Assembly has already been loaded.
    catch (BadImageFormatException imgEx)
    { } // If a BadImageFormatException exception is thrown, the file is not an Assembly.

    } // foreach dll
}
49
Jason S

このようにすることはできますが、アセンブリに有害なコードが含まれている可能性があるため、おそらくこのようにすべてを現在のappdomainにロードしないでください。

public IEnumerable<Assembly> LoadAssemblies()
{
    DirectoryInfo directory = new DirectoryInfo(@"c:\mybinfolder");
    FileInfo[] files = directory.GetFiles("*.dll", SearchOption.TopDirectoryOnly);

    foreach (FileInfo file in files)
    {
        // Load the file into the application domain.
        AssemblyName assemblyName = AssemblyName.GetAssemblyName(file.FullName);
        Assembly assembly = AppDomain.CurrentDomain.Load(assemblyName);
        yield return Assembly;
    } 

    yield break;
}

編集:コードをテストしていません(このコンピューターではVisual Studioにアクセスできません)が、アイデアが得られることを願っています。

6
Patrik Svensson