Ich habe eine Klassenbibliothek mit Hilfsklassen geschrieben. Wie kann ich diese Hilfsklasse so einsetzen, daß ich in verschiedenen Programmen die gleichen Klassen einsetzen kann. Ich benutze Visual Studio 2005 Beta 2.
Ich habe sowohl in dem Tutorial aus dem Forum als auch in Programmieren in C+ von Jesse Liberty geschaut und nichts gefunden.
Danke!
Lagere die Klassen in ein DLL aus...
Dieses kannst Du dann in allen Projekten referenzieren.
Früher war ich unentschlossen, heute bin ich mir da nicht mehr so sicher...
Da ich etwa das gleiche Problem habe und keinen neuen Thread aufmachen wollte, schreibe ich mal hier.
Ich habe eine Hauptanwendung (exe). Zudem ewig viele Module[DLLs] (Controls & Componenten) für diese Anwendung geschrieben und möchte gerne folgende Struktur haben:
Root:
EXE-File
Ordner Libs
Componente A (DLL)
Componente B (DLL)
...
Das hat den Sinn, dass mein Programm nicht jedes mal neu kompiliert werden muss, wenn eine DLL aktualisiert wurde. So brauche ich nur die DLL austauschen bei einem Update.
Jetzt meine eigentliche Frage: Wenn ich den Ordner Root (C:...Debug) verschiebe, stimmt ja eigentlich nicht mehr der Pfad zu den DLLs oder wird dieser dynamisch angepasst? Ist dieses Verfahren gut oder habt ihr Verbesserungsvorschläge? Achja LocalCopy lasse ich dann auf false, ne?
Die Art und Weise wie Assemblies zur Laufzeit aufgefunden werden ist in .NET recht ausgefuchst. Guckst du hier:
Prinzipiell funktioniert das Verschieben des Root-Verzeichnisses. Die festen Pfade, die du zur Design-Zeit für Referenzen angibst, werden zur Laufzeit nicht mehr benötigt sondern die Module dynamisch gesucht.
Also bei mir funktionierts nur, wenn die DLLs im Debugverzeichnis selbst liegen.
Mach ich aber ein Unterverzeichnis gehts nicht. Was habe ich vergessen?
Edit: Hab gerade mal einen ReferencePath gesetzt in den Projekteigenschaften. Jetzt stimmt der Pfad zur DLL wenn ich auf eigenschaften gehe. Im Desinger kann ich jetzt mit arbeiten, aber wenn ich kompiliere, findet er wieder das Control nicht...
Lies dir nochmal genau den englischen Text im verwiesenen Posting durch. Du kannst das auch in der MS-Hilfe nachlesen.
Und auch mein letztes Posting hier solltest du nochmal aufmerksam lesen:
"Die festen Pfade, die du zur Design-Zeit für Referenzen angibst, werden zur Laufzeit nicht mehr benötigt sondern die Module dynamisch gesucht."
Dein Control wird nicht gefunden, weil es nicht im .NET-Suchpfad deiner Anwendung ist. Die Designer-Referenzen haben damit nix zu tun. Normalerweise wird aber bei Referenzen auf Assemblies, die nicht im GAC sind, die referenzierte DLL mit in den Ausführungsordner (also Debug) kopiert (es sei denn du machst in den Referenz-Eigenschaften "Lokale Kopie" auf false). Es wird also nicht direkt die referenzierte Assembly genutzt, sondern eine Kopie im Anwendungsordner.
Dynamisch suchen hin oder her - es geht nicht!
Anfangs hatte ich ja auch verschiedene Verzeichnisse gehabt:
Controls
Es hat alles funktioniert und er hat auch die DLL in den Debugordner kopiert. Verschiebe ich aber eine eingebundene DLL (aus Controls zb. Panel) geht es nicht mehr! Leider werde ich aus dem englischen Text nicht wirklich schlau. Es wäre super, wenn du mir weiterhilfst.
Hier nochmal ein Link für eine Beschreibung in Deutsch (ab Seite 8).
http://www.ssw.uni-linz.ac.at/Teaching/Lectures/Sem/2003/reports/Steinbacher/Steinbacher.pdf
Hier nochmal ein Link für eine Beschreibung in Deutsch (ab Seite 8 ).
http://www.ssw.uni-linz.ac.at/Teaching/Lectures/Sem/2003/reports/Steinbacher/Steinbacher.pdf
Und noch eine Zusammenfassung (http://www.entwickler-forum.de/webx?50@214.ttcmabsxdvf.0@.2cb7e309):
"Das Laden einer Assembly lässt sich in verschiedene Arbeitsschritte unterteilen. Zuerst such die CLR nach einer anwendungsspezifischen Konfigurations-Datei mit der Dateiendung .config. Wird dies gefunden, sucht die CLR dort nach Einträgen, die den Ladevorgang beeinflussen – wie zum Beispiel CodeBase oder privatePath. Außerdem wird die Assembly auch im AppBase-Verzeichnis (also dem Installationsverzeichnis der aufrufenden Anwendung) gesucht. Nur dann, wenn die angeforderte DLL einen Strong Name besitzt, sucht die CLR auch im Global Assembly Cache (GAC). Ist auch dort keine passende Assembly aufzutreiben, berücksichtigt die CLR die vorgefundenen Versionsnummern-Policies, so dass ein "Umbiegen" auf andere Versionsnummern unterstützt wird.
Das Tool Assembly Binding Log Viewer (FUSLOGVW.EXE) protokolliert genau mit, wo die CLR überall nach dieser Assembly gesucht hat, bevor die Exception geworfen wurde. "
Sorry für den Doppel-Post. Scheint sich um einen Bug im Zuge der 30-Sekunden-Sperre zu handeln.
Ansich ne coole Sache. Im andren Beitrag schreibst du auf die Frage wo man den Path setzt:
This location can be specified in the application configuration file and in managed code using the AppendPrivatePath property for an application domain.
Wo finde ich denn dieses config-File?
Selbst schreiben! Ihr name lautete namederexe.config, also für foobar.exe lautet sie foobar.exe.config. (BTW: Wenn du in Visual Studio eine app.config zum Projekt hinzufügst, übernimmt VS das Kopieren und Umbennen selbst).
Doku:
http://msdn.microsoft.com/library/en-us/cpgenref/html/gngrfNETFrameworkConfigurationFileSchema.asp
Du suchst: <configuration><runtime><assemblyBinding><probing>
Oh, und ich schieb es mal nach Rund um....
Ah cool ja. Also wenn ich richtig gelesen habe, ist es einfach nur ein XML-Dokument, welches ich dann applicationname.exe.config nennen muss. Reicht es, wenn ich in meinem Projekt "Add" -> "New Item" -> "XML File" mache und dort den Code
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<probing privatePath="bin;bin\\Libs"/>
</assemblyBinding>
</runtime>
</configuration>
einfüge?
"Add" -> "New Item" -> "Application configuration file"
geht auch. Nennt sich dann App.config und wird beim build autom. umbenannt.
Wollte nur mal sagen, dass es super funzt. Danke an alle =)
Aber ne kleine Frage bleibt doch noch:
Was ist wenn eine eingebundene dll ausgetauscht wurde (gegen eine neuere Version)? Bei mir kommt leider ein Fehler "...already been imported". Weil dafür sollte ja die Grundidee sein, damit ich per Update nur dlls austauschen muss, statt jedes mal die Exe mitzuschicken.
Hallo -acid-,
"...already been imported" klingt nach Assembly.Load. Wenn ich das richtig verstehe, würde dir aber statisches Linken reichen (also DLLs beim Compilieren Referenzieren).
Wenn du es wirklich mit Assembly.Load machst, sollte dir dlls freigeben helfen.
herbivore
Hallo -acid-!
Wenn Du Visual Studio benutzt, kannst Du die Dll's auf 2 verschiedene Arten und Weisen eibinden, indem Du die DLL normal einbindest, dann beim Solution-Explorer auf die eingebundene DLL klickst und im Property Window die Einstellung "Copy Local" von "True" auf "False" setzt.
Das bewirkt, dass er die DLL nicht ins Projektverzeichnis kopiert, sondern immer von der angegebenen Stelle referenziert. Das heißt, dass bei einer Änderung der DLL alle Projektreferenzen auf einmal aktualisiert worden sind 😉
Nachdem Du Deine Software fertig entwickelt hast (im Speziellen Deine DLL) kannst Du die oben genannte Einstellung rückgängig machen und Dir die DLL dann ins Projektverzeichnis kopieren lassen...
Ciao
Norman-Timo
A: “Wie ist denn das Wetter bei euch?”
B: “Caps Lock.”
A: “Hä?”
B: “Na ja, Shift ohne Ende!”
Also das mit true/false ist mir schon klar Nochmal zur meiner Situation:
Ich entwickle an meiner exe die eigentlich nie fertig wird. Genausowenig werden die meisten dlls auchn ie fertig werden. Daher soll die Ordnerstruktur sein:
Exe (Das ist Root)
libs (Ordner für Dlls)
Wenn der Enduser dann ein Update macht, brauchen nur teilweise die Module upgedatet zu werden, sprich einfach nur die Dlls ausgetauscht werden (im seltesten Fall die Exe).
Genau diese Struktur habe ich jetzt und füge aus "libs" die dlls ein. Übe ich allerdings den Ernstfall, dass eine dll eine neue Version hat und ins "libs" Verzeichnis kopiert wird, startet meine Exe nicht mehr. Wie soll ich da vorgehen? Und nochmals: Ich will nicht, dass die dlls im Root liegen...
Hier nochmal ein komplettes Kapitel eines Buches zum Thema Assemblies und Deployment:
svenson wirklich vielen Dank für deine Hilfe. Das Buch hat mich schon etwas weiter gebracht. Leider nicht zum Ziel.
Also ich habe das so verstanden, dass es KEINE Versionsunterschiede bei meinen Dlls gibt. Daher bringt er den Fehler. Ich benötige also nun den StrongName und irgendwas muss ich mit dieser sn.exe machen... aber mir fehlt noch der richtige Durchblick. Kannst du/könnt ihr mir weiterhelfen?
Ich habe meine App.config schonmal erweitert:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<probing privatePath="libs"/>
<bindingRedirect oldVersion="*" newVersion="*"/>
</assemblyBinding>
</runtime>
</configuration>
Nochmal eine Idee: In einem der letzten Positing von mir wurde ein Tool erwähnt, mit dem man den Ladevorgang überwachen kann. Bitte besorge dir das und schmeisse hier mal den Output und die genau Fehlerrmeldung, zur Not als Screenshot hier rein. Solche Problem sind immer ziemlich knifflig und bedürfen einer absolut exakten Fehlerbeschreibung.