10

バイト配列だけを使用してアセンブリを読み込んで実験していますが、正しく動作させる方法がわかりません。セットアップは次のとおりです。

public static void Main() 
{
    PermissionSet permissions = new PermissionSet(PermissionState.None);
    AppDomainSetup setup = new AppDomainSetup { ApplicationBase = Environment.CurrentDirectory };
    AppDomain friendlyDomain = AppDomain.CreateDomain("Friendly", null, setup, permissions);

    Byte[] primary = File.ReadAllBytes("Primary.dll_");
    Byte[] dependency = File.ReadAllBytes("Dependency.dll_");

    // Crashes here saying it can't find the file.
    friendlyDomain.Load(dependency);

    AppDomain.Unload(friendlyDomain);

    Console.WriteLine("Stand successful");
    Console.ReadLine();
}

2 つのモック dll を作成し、システムが物理ファイルを見つけられないように、意図的に拡張子を '.dll_' に変更しました。両方ともprimary正しくdependency入力されますがAppDomain.Load、バイナリ データでメソッドを呼び出そうとすると、次のように返されます。

Could not load file or assembly 'Dependency, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The system cannot find the file specified.

システムでファイルを検索するのはなぜですか?

アップデート

一方、これはうまくいくようです:

public class Program {
    public static void Main() {
        PermissionSet permissions = new PermissionSet(PermissionState.Unrestricted);
        AppDomainSetup setup = new AppDomainSetup { ApplicationBase = Environment.CurrentDirectory };
        AppDomain friendlyDomain = AppDomain.CreateDomain("Friendly", null, setup, permissions);

        Byte[] primary = File.ReadAllBytes("Primary.dll_");
        Byte[] dependency = File.ReadAllBytes("Dependency.dll_");

        // Crashes here saying it can't find the file.
        // friendlyDomain.Load(primary);

        Stage stage = (Stage)friendlyDomain.CreateInstanceAndUnwrap(typeof(Stage).Assembly.FullName, typeof(Stage).FullName);
        stage.LoadAssembly(dependency);

        Console.WriteLine("Stand successful");
        Console.ReadLine();
    }

}

public class Stage : MarshalByRefObject {
    public void LoadAssembly(Byte[] data) {
        Assembly.Load(data);
    }
}

AppDomain.Loadしたがって、 と の間には違いがあるようAssembly.Loadです。

4

3 に答える 3

5

これら 2 つの方法に違いはありません (必要に応じて、公式のソース コードを確認できます)。

AppDomain.Load メソッド (Byte[])の MSDN ページでは、このメソッドが現在のアプリケーション ドメインにアセンブリをロードしていることに注意してください。

このメソッドは、アセンブリを現在のアプリケーション ドメインに読み込む場合にのみ使用してください。このメソッドは、静的な Assembly.Load メソッドを呼び出すことができない相互運用性の呼び出し元の便宜のために提供されています。アセンブリを他のアプリケーション ドメインに読み込むには、CreateInstanceAndUnwrap などのメソッドを使用します。

この線:

friendlyDomain.Load(dependency);

次の場合とまったく同じように動作します。

Assembly.Load(dependency);

更新されたサンプル コードで機能する理由は、Stageオブジェクトが実際にAppDomainAssembly.Load内で呼び出しているためです。

注: この回答は、Hans Passant と colinsmith による回答を補完します。

于 2013-07-25T14:27:11.033 に答える
0

使用FusionLogViewerすると、CLR がアセンブリをロードする際に発生している特定の問題についての詳細を確認できます。手がかりを得るためにプローブしようとしている場所を表示できます。

コード内でAssemblyLoad / AssemblyResolve / ResourceResolve イベントを処理しAppDomainて、シーケンスをトレースすることもできます。

これは、カスタム MSBuild ステップを使用して、プロジェクトに依存するアセンブリをリソースとして EXE プログラムに埋め込み、それらを( byte[] 配列で実行して)AssemblyResolveからロードするために使用する便利な例です。ResourceStreamAssembly.Load()

于 2013-07-24T14:26:20.867 に答える