Die Baugruppe kann keine referenzierte Baugruppe finden, wenn sie mit codedomProvider zum Speicher kompiliert wird

StackOverflow https://stackoverflow.com/questions/6804147

Frage

Ich versuche, zur Laufzeit einen Code zum Speicher mit einem codedomProvider zu kompilieren.

Der Code, den ich kompiliere, verweist auf eine externe Montage, die ich in die Parameter einbeziehe, die beim Kompilieren des Codes verwendet werden.

Wenn ich zum Gedächtnis kompiliere und versuche, Reflexion auf der in einem Visual Studio-Add-In generierten Baugruppe zu verwenden, bringt eine Ausnahme aus, dass sie die referenzierte Baugruppe nicht finden kann.

(Ausnahme)
"Ein oder mehrere der angeforderten Typen kann nicht geladen werden. Abrufen Sie die Eigenschaft loadExceptions für weitere Informationen ab."

(LoadErException)
"{" Konnte keine Datei oder Assemblierung 'dynamo.jiss.task, Version = 1.0.0.0, Culture = neutral, publicKeyToken = null' oder eine seiner Abhängigkeiten laden. Das System kann die angegebene Datei nicht finden. ":" Dynamo.jiss.task, Version = 1.0.0.0, Culture = neutral, publicKeyToken = null "}"

Ich habe versucht, die Baugruppe mit dem absoluten Pfad aus verschiedenen Orten zu verweisen.

Der genau gleiche Code funktioniert einwandfrei, wenn er von einer Konsolenanwendung ausgeführt wird, und er funktioniert auch im Add-In gut, wenn ich nicht zum Speicher kompile.
Das Entfernen der Referenz auf die externe Baugruppe und den Code, auf den sie referenziert, funktioniert auch beim Kompilieren in den Speicher. Daher ist sie wahrscheinlich ein Problem beim Laden der referenzierten Montage.

Hat jemand eine Idee, warum das Kompilieren des Speichers und das Verweisen auf eine Baugruppe nicht in einem Add-In funktioniert?

Gibt es einige Einschränkungen innerhalb der Appdomain, die es ausgeführt wird, oder etwas, das mir bekannt sein sollte? (meine derzeit beste Vermutung)

Sollte es in einem bestimmten Ordner sein? Referenziert unter Verwendung eines relativen Pfades? Sicherheitseinstellungen? Muss unterschrieben werden? irgendwelche Ideen?


Was ich erreichen möchte, ist eine Möglichkeit, Dateien mit einer bestimmten Erweiterung in ein Projekt einzulegen und das Addin automatisch kompilieren zu lassen. Wenn es eine ITask -Schnittstelle (aus der externen Montage) implementiert Möglicherweise, damit der Code in die Visual Studio -Ereignisse einbezieht und Aufgaben/Skripte ausführen kann, während Sie sich die verschiedenen Ereignisse anhören. Auf diese Weise kann ich leicht Textvorlagen ausführen, wenn eine andere Datei geändert wird, oder Dateien zu verschiedenen Ereignissen (Dokument gespeichert, erstellen usw.) geändert und miniieren.

Gibt es schon so etwas (um mich vom Schmerz zu entlasten)? :)

War es hilfreich?

Lösung

Dies geschieht höchstwahrscheinlich, weil Sie Codedom sagen, dass Sie eine In-Memory-Baugruppe generieren sollen (was wirklich eine Lüge ist, da sie vorübergehend zum Festplatten generiert, geladen und dann die Datei löschen). Der Punkt ist, dass das Compile -Verzeichnis für die codierte Montage nicht derselbe ist wie das, das Sie zum Kompilieren verwenden. Das heißt, wenn Sie in Bin Debug läuft, wird die codierte Montage zu %temp %generiert.

Sie könnten dies auf zwei Arten lösen, an die ich denken kann:

  1. Kompilieren Sie die codierte Montage auf denselben Weg wie Ihre ausführende Montage.

    myCodeProvider.GenerateInMemory = false; // may not be necessary...haven't tried this in a while
    myCodeProvider.OutputAssembly = string.Format(@"{0}\{1}", Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location, "mydll.dll");
    
  2. Behandeln Sie das AssemblyResolve -Ereignis und geben Sie der codierten Montage die angeforderte Referenzbaugruppe an.

    AppDomain.CurrentDomain.AssemblyResolve += OnCurrentDomainAssemblyResolve
    
    private static Assembly OnCurrentDomainAssemblyResolve(object sender, ResolveEventArgs args)
    {
                    // this is absurdly expensive...don't do this more than once, or load the assembly file in a more efficient way
                    // also, if the code you're using to compile the CodeDom assembly doesn't/hasn't used the referenced assembly yet, this won't work
                    // and you should use Assembly.Load(...)
                    foreach (Assembly @assembly in AppDomain.CurrentDomain.GetAssemblies())
                    {
                        if (@assembly.FullName.Equals(args.Name, StringComparison.OrdinalIgnoreCase))
                        {
                            return @assembly;
                        }
                    }
    }
    
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top