Entwickler-Ecke

Basistechnologien - Probleme mit Einbinden von DLLs


Telefisch - Fr 13.06.08 11:01
Titel: Probleme mit Einbinden von DLLs
Hallo Forum...
ich bin bereits seit einigen Wochen einem Problem auf den Fersen und hab schon hunderte von Beiträgen dazu gelesen.
Mein Problem sieht folgendermaßen aus:
Ich habe ein AddIn für Excel erstellt und muss dort eine API-DLL eines Drittanbieters einbinden.
Erstes Problem, diese API kann aufgrund unterschiedlicher Softwarestände des Anbieters in unterschiedlichen verzeichnissen liegen.
Wegen regelmäßiger Updates der Software des Drittanbieters kann ich die API nicht mit ausliefern.
Ich hab mir also erstmal einen Verzeichnisstring besorgt (Dateidialog etc..)

Dieses Verzeichnis wird beim Laden des AddIns mit

C#-Quelltext
1:
            Environment.CurrentDirectory = strBIN;                    

gesetzt.
Sollte es Probleme geben, gibts natürlich auch nen Event:

C#-Quelltext
1:
2:
            AppDomain MyAppDomain = AppDomain.CurrentDomain;
            MyAppDomain.AssemblyResolve += new ResolveEventHandler(appDomain_AssemblyResolve);

Natürlich wird IMMER! ein Problem gefunden (sonst wärs ja schon gelöst)

C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
        Assembly appDomain_AssemblyResolve(object sender, ResolveEventArgs args) // Assembly laden
        {

            Assembly MyAssembly;

            string strTempAssmbPath = strBIN + @"\" + args.Name.Substring(0, args.Name.IndexOf(",")) + ".dll";

            //Load the assembly from the specified path. 

            Environment.CurrentDirectory = strBIN;  //nur zur Sicherheit

            MyAssembly = Assembly.LoadFile(strTempAssmbPath);

            //MyAssembly = Assembly.LoadFrom(strTempAssmbPath);   //hat auch ncht funktioniert

            //Return the loaded assembly.

            return MyAssembly;

        }

Wenn ich nun eines dieser API-Objekte benötige wird der Event ausgelöst, so weit so gut.
Sobald der Debug-Cursor zur Zeile "MyAssembly = Assembly.LoadFile(strTempAssmbPath);" kommt, bricht das Programm völlig emotionslos ab.

Das Einzige was ich an Antworten vom VS bekomme ist:
Eine Ausnahme (erste Chance) des Typs "System.Security.Policy.PolicyException" ist in mscorlib.dll aufgetreten.
Eine Ausnahme (erste Chance) des Typs "System.IO.FileLoadException" ist in mscorlib.dll aufgetreten.
Eine Ausnahme (erste Chance) des Typs "System.IO.FileLoadException" ist in DDT_ASG_EPL2003.DLL aufgetreten.
Eine Ausnahme (erste Chance) des Typs "System.Reflection.TargetInvocationException" ist in mscorlib.dll aufgetreten.

Natürlich hab ich mit dem Hersteller der API gesprochen. Hier seine Kommentare:
"leider ist das mit .Net allse etwas komplizierter geworden. "
"Das Visual Studio ist zusätzlich so "schlau", normalerweise die referenzierten Assemblies lins lokale bin-Verzeichnis der Applikation zu kopieren. "
"Das macht die Sache leider noch schlimmer, da die Applikation dann meint, die Assemblies gefunden zu haben, diese finden aber dan wiederum die weitergehenden Abhängigkeiten nicht :("

"bei mir funktionieren dies VSTO Programme auch nicht immer. Manchmal meint .NET, es habe die Assemblies gefundenen zu haben, hat aber in Wirklichkeit die falschen und kann diese dann nicht laden."

"Anbei ein Beispiel für ein kleines Offline-Programm, mit dem man eine Excel-Tabelle von außen ausliest. Ich würde vorschlagen, Sie verfrachten die EPLAN-Logik in ein kleines Executable, das Sie" "ins EPLAN bin Verzeichnis installieren. Diese exe rufen Sie dann von Ihrer Excel-Tabelle aus auf (System.Diagnostics.Process.Start(...)) und übergeben den Namen der Tabelle als Parameter ...."

"die API-Assemblies haben Abhängigkeiten zu statisch gelinkten klassischen C++ Dlls. Diese müssen im Pfad sein, damit sie geladen werden können. Das Laden der API Assemblies schlägt fehl, wenn diese unmanaged dlls nicht geladen werden können."

"Normalerweise reicht es aus, irgendwann ziemlich am Anfang Environment.CurrentDirectory auf den Pfad des BIN-Verzeichnis von P8 zu setzen."

"Bitte senden Sie mir noch mal Ihr Beispiel. Vielleicht kann ich es so umbauen, dass die Assemblies geladen werden."

Der oben geschriebene Event (hab ich selbst auch schon so gehabt) war seine Antwort.

Lustigerweise funktioniert das ganze auf seinem Rechner. Wie kann das sein (Rechtevergaben vielleicht?) und wie kann ich sicher stellen, dass ich nicht die gleichen Probleme bekomme, wenn das AddIn auf anderen Stationen ausgeführt wird?

Ich bin mittlerweile echt verzweifelt. Kann mir jemand helfen?

Gruss Carsten

Moderiert von user profile iconChristian S.: Code- durch C#-Tags ersetzt


JüTho - Fr 13.06.08 11:57

Oh je... Wirklich helfen kann ich nicht, weil ich bisher nur eigene DLLs und "originäre" NET-DLLs einbinde. Aber vielleicht helfen Dir meine Hinweise weiter.

Eine PolicyException deutet in der Tat auf Probleme mit den Rechten hin. Ich könnte mir vorstellen, dass alle weiteren Fehlermeldungen nur Folgeprobleme sind.

Eine DLL nutzt eigentlich keine app.config. Aber vielleicht kannst Du ConfigurationManager.OpenMappedExeConfiguration "vergewaltigen", sodass Du diese in das Verzeichnis Deiner DLL legst und daraus den Pfad/Dateinamen der Fremd-DLL auslesen kannst. Freilich weiß ich nicht, wie oft dieser Pfad sich durch Updates ändert.

Den Hinweis mit "LocalCopy = false" solltest Du auf jeden Fall berücksichtigen. Das ist auch in anderen Fällen meistens sinnvoller.

Viel Erfolg! Jürgen