从C / CLI中相互依赖的组件
-
21-09-2019 - |
题
我想加载从C / CLI两个组件;组件A依赖于组件B,又都是VB.Net项目(3.5)。我希望他们能够从一个字节数组加载,所以我用大会:: 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;
}
的错误是:
无法加载文件或程序集 '的 AssemblyB,版本= 1.0.3650.39903文化=中性公钥=空强>' 或它的一个依赖。系统不能找到指定的文件。
当我检查assemblyb->全名,它说正好 '的 AssemblyB,版本= 1.0.3650.39903文化=中性公钥=空强>'。
当然,如果我复制AssemblyB.dll我的测试程序文件夹中的代码工作得很好,但是这不是我想要的。
任何想法?
(顺便说,我的第二步骤将是企图使AssemblyA使用类,我的C ++ / CLI exe将暴露。)
解决方案
OK,我只是不好意思自己。这一切都在船坞。
// 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);
.
.
.
我希望有人认为这是有用的。 :)
不隶属于 StackOverflow