20

AssenblyResolveイベントにしばらく苦労しています。私はstackoverflowを検索し、他のグーグルを実行し、関連すると思われるすべてを試しました。これが私の問題に近いリンクです(私の意見では):

  1. AssemblyResolveは呼び出されず、シリアル化中にFileNotFoundExceptionがスローされます

  2. クラスライブラリのAssemblyResolveイベントを処理する場所はどこですか?

静的メソッドを持つBootstrapperクラスがあります(わかりやすくするために、スレッドセーフなコードを削除します:

public static void Initialize()
{
    AppDomain.CurrentDomain.AssemblyResolve += CustomResolve;
}

private static Assembly CustomResolve(object sender, ResolveEventArgs args)
{
    // There is a lot code here but basicall what it does.
    // Is determining which architecture the computer is running on and
    // extract the correct embedded dll (x86 or x64). The code was based
    // on milang on GitHub (https://github.com/milang/P4.net). And it's the same
    // purpose we want to be able to load the x86 or x64 version of the perforce dll
    // but this time with the officially Perforce supported p4api.net.
    // Once the dll is extracted we assign it to the boostrapper
    Bootstrapper._p4dnAssembly = Assembly.LoadFile(targetFileName);

    // Make sure we can satisfy the requested reference with the embedded assembly (now extracted).
    AssemblyName reference = new AssemblyName(args.Name);
    if (AssemblyName.ReferenceMatchesDefinition(reference, Bootstrapper._p4dnAssembly.GetName()))
    {
        return Bootstrapper._p4dnAssembly;
    }
}

mainメソッドと静的コンストラクターを持つ単純なクラスがあれば、コードを機能させることができました。静的コンストラクターは、単にBoostrapper.Initialize()メソッドを呼び出しています。その後、ライブラリを使用でき、期待どおりに機能していました。

public static class Test
{
    static Test()
    {
        Bootstrapper.Initialize();
    }

    public static void Main()
    {
         // Using the library here is working fine. The AssemblyResolve event was
         // fired (confirmed by a breakpoint in Visual Studio)
    }
}

私が抱えている問題は、依存関係の層が少なくとも1つあるかどうかです。基本的にコードは同じままですが、今回はライブラリのコードが別のライブラリ内にあります。

public static class Test
{
    static Test()
    {
        Bootstrapper.Initialize();
    }

    public static void Main()
    {
        Class1 myClass = new Class1();

        // The following line is using the code of the extracted library, but
        // The AssemblyResolve event is not fired (or fired before I register the  
        // callback) and therefore the library is not found : result  
        // BadImageFormatException() error could not load libary because one
        myClass.Connect();
    }
}

私が以前に述べたリンクの#2のように聞こえますが、私が見ているものを説明していますが、それは機能しません。AssemblyResoveコールバックのVisualStudioブレークポイントがヒットすることはありません。

何が起こっているのかについて何か考えはありますか?

フランシス

4

2 に答える 2

34

この質問に答えてからしばらく経ちましたが、とにかくこの問題についての私の見解を追加したいと思いました(これで数時間を無駄にしたので、おそらくこれのおかげで他の誰かがする必要はありませんでした)

問題は基本的に、アプリケーションがメソッドの開始時にメソッドを実行するために必要なすべてのアセンブリを解決しようとしているという事実です。

static void main(string[] args)
{
    // <-- here the app tries to resolve MyAssembly
    // and as MyAssembly.Class1 is not found, the app crashes

    // this next line is never called:
    AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(ResolveAssembly);

    // class contained in an assemnly that we need to resolve
    MyAssembly.Class1 myClass = new MyAssembly.Class1();
}

上記がクラッシュするのはそのためです。ResolveAssemblyイベントハンドラーは、接続されていないため、呼び出されることはありません。

そして、それが以下の解決策が機能する理由でもあります(OPによって投稿されたように):

static void main(string[] args)
{
    Initialize();
    RealMain();
}

static void Initialize()
{
    AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(ResolveAssembly);
}

static void RealMain()
{
   // <-- here the app tries to resolve MyAssembly
   // class contained in an assemnly that we need to resolve      
   MyAssembly.Class1 myClass = new MyAssembly.Class1();
   // and everything is OK
}
于 2014-09-23T09:00:14.053 に答える
11

誰かが答えましたが、答えは削除されました。だから私はそれを回答済みとしてマークすることはできません。基本的に、コードが「メイン」メソッドの外にある必要がないという事実は機能しています。新しいプロジェクトから始めて、問題を解決して、dllに問題があったと思います(おそらくx64フォルダー内のx86 dll、またはその逆)。

static void main(string[] args)
{
    Boostrapper.Initialize();
    RealMain();
}

static void RealMain()
{
    Class1 myClass = new Class1();
    myClass.Connect();
}
于 2012-10-30T18:27:06.513 に答える