Question

Je veux charger deux ensembles de C ++ / CLI; Ensemble A dépend de l'assemblage B, et les deux sont des projets VB.Net (3.5). Je veux qu'ils charger à partir d'un tableau d'octets, donc j'utiliser l'Assemblée Load (), mais lorsque je tente d'instancier une classe d'assemblage A, le cadre ne tient pas compte B d'assemblage précédemment chargé et tente de le charger à nouveau, ce qui échoue parce que il est pas dans le chemin de recherche. Le « nom » de l'ensemble est la même chose, donc je ne sais pas pourquoi il échoue. Pour des fins de test, mon programme charge les octets directement à partir de l'image compilé, mais le code réel sera chargé différemment. Ceci est mon code de test:

#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;
}

L'erreur est:

Impossible de charger le fichier ou l'assembly ' AssemblyB, Version = 1.0.3650.39903, Culture = neutral, PublicKeyToken = null ' ou une de ses dépendances. Le système ne peut pas trouver le fichier spécifié.

Quand je vérifie assemblyb-> FullName, il dit exactement « AssemblyB, Version = 1.0.3650.39903, Culture = neutral, PublicKeyToken = null .

Bien sûr, si je copie AssemblyB.dll dans le dossier de mon programme d'essai, le code fonctionne très bien, mais ce n'est pas ce que je veux.

Toutes les idées?

(Soit dit en passant, ma deuxième étape sera de tenter de faire des cours d'utilisation AssemblyA que mon C ++ / CLI exe exposera.)

Était-ce utile?

La solution

OK, je me suis juste embarrassé. Il est dans les docks.

// 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);
.
.
.

J'espère que quelqu'un trouve cela utile. :)

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top