C++ cli 从C+加载相互依赖的程序集+/CLI

C++ cli 从C+加载相互依赖的程序集+/CLI,c++-cli,filenotfoundexception,assembly.load,C++ Cli,Filenotfoundexception,Assembly.load,我想从C++/CLI加载两个程序集;程序集A依赖于程序集B,两者都是VB.Net项目(3.5)。我希望它们从字节数组加载,所以我使用Assembly::load(),但是当我尝试从程序集a实例化一个类时,框架会忽略以前加载的程序集B并尝试再次加载它,这会失败,因为它不在搜索路径中。程序集的“名称”是相同的,所以我不知道它为什么失败。出于测试目的,我的程序直接从编译后的图像加载字节,但实际代码的加载方式不同。这是我的测试代码: #include "stdafx.h" using namespac

我想从C++/CLI加载两个程序集;程序集A依赖于程序集B,两者都是VB.Net项目(3.5)。我希望它们从字节数组加载,所以我使用Assembly::load(),但是当我尝试从程序集a实例化一个类时,框架会忽略以前加载的程序集B并尝试再次加载它,这会失败,因为它不在搜索路径中。程序集的“名称”是相同的,所以我不知道它为什么失败。出于测试目的,我的程序直接从编译后的图像加载字节,但实际代码的加载方式不同。这是我的测试代码:

#include "stdafx.h"

using namespace System;
using namespace System::Windows::Forms;
using namespace System::IO;
using namespace System::Reflection;

[STAThreadAttribute]
int main(array<System::String ^> ^args)
{
    array<unsigned char>^   bytes;
    FileStream^     f;

    f = gcnew FileStream(L"c:\\...\\AssemblyB.dll", FileMode::Open);
    bytes = gcnew array<unsigned char>((int)f->Length);
    f->Read( bytes, 0, (int) f->Length );
    f->Close();
    f = nullptr;
    Assembly^   assemblyb = Assembly::Load(bytes);

    f = gcnew FileStream(L"c:\\...\\AssemblyA.dll", FileMode::Open);
    bytes = gcnew array<unsigned char>((int)f->Length);
    f->Read( bytes, 0, (int) f->Length );
    f->Close();
    f = nullptr;
    Assembly^   assemblya = Assembly::Load(bytes);

    bytes = nullptr;

    // Here I get the file not found exception!
    Object^     mf = assemblya->CreateInstance(L"AssemblyA.MainForm");

    // This line is not reached unless I copy assemblyb.dll to my app's folder:
    mf->GetType()->InvokeMember(L"ShowDialog",BindingFlags::Default | BindingFlags::InvokeMethod,
                                mf->GetType()->DefaultBinder, mf, nullptr );

    return 0;
}
#包括“stdafx.h”
使用名称空间系统;
使用命名空间System::Windows::Forms;
使用名称空间系统::IO;
使用名称空间系统::反射;
[属性]
int main(数组^args)
{
数组^字节;
文件流^f;
f=gcnewfilestream(L“c:\\…\\AssemblyB.dll”,FileMode::Open);
字节=gcnew数组((int)f->Length);
f->Read(字节,0,(int)f->Length);
f->Close();
f=空PTR;
Assembly^assemblyb=Assembly::Load(字节);
f=gcnewfilestream(L“c:\\…\\AssemblyA.dll”,FileMode::Open);
字节=gcnew数组((int)f->Length);
f->Read(字节,0,(int)f->Length);
f->Close();
f=空PTR;
Assembly^assemblya=Assembly::Load(字节);
字节=空ptr;
//在这里我得到的文件找不到异常!
对象^mf=assemblya->CreateInstance(L“assemblya.MainForm”);
//除非我将assemblyb.dll复制到我的应用程序文件夹中,否则无法到达此行:
mf->GetType()->InvokeMember(L“ShowDialog”,BindingFlags::Default | BindingFlags::InvokeMethod,
mf->GetType()->DefaultBinder、mf、nullptr);
返回0;
}
错误是:

无法加载文件或程序集“AssemblyB,版本=1.0.3650.39903,区域性=中性,PublicKeyToken=null”或其依赖项之一。系统找不到指定的文件

当我选中assemblyb->FullName时,它会准确地显示“assemblyb,Version=1.0.3650.39903,Culture=neutral,PublicKeyToken=null

当然,如果我将AssemblyB.dll复制到测试程序的文件夹中,代码工作正常,但这不是我想要的

有什么想法吗


(顺便说一下,我的第二步将尝试使AssemblyA使用我的C++/CLI exe将公开的类。)

好的,我只是让自己尴尬了。都在文件里

// This class is just for holding a managed static variable for assemblyB
ref class Resolver {
public:
    static  Assembly^   assemblyB;
};

// This is the delegate for resolving assemblies
Assembly^ ResolveHandler(Object^ Sender, ResolveEventArgs^ args)
{
    // Warning: this should check the args for the assembly name!
    return Resolver::assemblyB;
}
.
.
.
[STAThreadAttribute]
int main(array<System::String ^> ^args)
{
    // Set up the handler for the AssemblyResolve event
    AppDomain::CurrentDomain->AssemblyResolve += gcnew ResolveEventHandler( ResolveHandler );
.
.
.
    // Load assemblyb into the static variable available to the resolver delegate
    Resolver::assemblyb = Assembly::Load(bytes);
.
.
.
//此类仅用于保存assemblyB的托管静态变量
ref类解析器{
公众:
静态汇编^assemblyB;
};
//这是用于解析程序集的委托
程序集^ResolveHandler(对象^Sender,ResolveEventArgs^args)
{
//警告:这应该检查args中的程序集名称!
返回解析器::assemblyB;
}
.
.
.
[属性]
int main(数组^args)
{
//设置AssemblyResolve事件的处理程序
AppDomain::CurrentDomain->AssemblyResolve+=gcnew ResolveEventHandler(ResolveHandler);
.
.
.
//将assemblyb加载到解析器委托可用的静态变量中
解析器::assemblyb=Assembly::Load(字节);
.
.
.

我希望有人会觉得这很有用。:

Mmmm…从我在这里读到的()看来,我应该实现一个ResolveHandler,但我对C++/CLI中AddHandler()的语法一无所知!:p