تحميل تجميعات مترابطة من C ++/CLI
-
21-09-2019 - |
سؤال
أريد تحميل تجميعين من C ++/CLI ؛ يعتمد التجميع A على التجميع B ، وكلاهما مشاريع VB.NET (3.5). أريدهم أن يتم تحميلهم من صفيف بايت ، لذلك أستخدم Assembly :: load () ، لكن عندما أحاول إنشاء فصل دراسي من التجميع أ ، يتجاهل الإطار التجميع الذي تم تحميله مسبقًا ويحاول تحميله مرة أخرى ، والذي يفشل بسبب ليس في مسار البحث. "اسم" التجميع هو نفسه ، لذلك لا أعرف لماذا يفشل. لأغراض الاختبار ، يقوم برنامجي بتحميل البايتات مباشرة من الصورة المترجمة ، ولكن سيتم تحميل الكود الحقيقي بشكل مختلف. هذا هو رمز الاختبار الخاص بي:
#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 ، الثقافة = محايد ، publickeytoken = خاليةأو واحدة من تبعياتها. لا يمكن للنظام العثور على الملف المحدد.
عندما أتحقق من AssemblyB-> fullname ، يقول بالضبط "AssemblyB ، الإصدار = 1.0.3650.39903 ، الثقافة = محايد ، publickeytoken = خالية'.
بالطبع ، إذا قمت بنسخ AssemblyB.dll إلى مجلد برنامج الاختبار الخاص بي ، فإن الرمز يعمل بشكل جيد ، لكن هذا ليس ما أريده.
أيه أفكار؟
(بالمناسبة ، ستكون خطوتي الثانية هي محاولة لجعل الفصول التي تستخدمها Covery 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);
.
.
.
آمل أن يجد شخص ما هذا مفيدًا. قون