Kompilieren eine version Agnostiker DLL in .NET
Szenario
Habe ich zwei Wrapper für Microsoft Office, eines für 2003 und eine für das Jahr 2007. Da beide Versionen von Microsoft Office, die mit der side-by-side "nicht offiziell möglich", noch von Microsoft empfohlen, wir haben zwei Boxen, eine mit Office 2003 und das andere mit Office 2007. Wir stellen die Wrapper getrennt. Die DLLs sind in unserer Lösung, jede box hat die gleichen Kasse aber mit Office 2003 oder 2007 "entladen", damit es nicht versucht zu kompilieren, dass bestimmte DLL. Versagen zu tun, die werfen Fehler auf Zusammenstellung durch das Office-COM-DLLs nicht zur Verfügung.
Verwenden wir .NET 2.0 und Visual Studio 2008.
Fakten
Da Microsoft auf mysteriöse Weise verändert das Office 2003-API im Jahre 2007 eine Umbenennung und änderung einiger Methoden (Seufzer) damit Sie nicht rückwärts kompatibel, wir müssen die zwei Wrapper.
Wir haben jede Baumaschine mit der Lösung und einem Office-DLL aktiviert. E. g.: die Maschine mit Office 2003 hat das "Office 2007" DLL entladen, daher nicht kompilieren. Das andere Feld ist die gleiche Idee, aber die andere Weise herum. All dies, weil wir können nicht 2 verschiedene Office in der gleichen box zur Programmierung. (könnte man technisch zwei Office zusammen, laut Microsoft), aber nicht für die Programmierung und nicht ohne einige Probleme.
Problem
Wenn wir ändern die Version der Anwendung (von 1.5.0.1 zu 1.5.0.2 zum Beispiel) benötigen, kompilieren Sie die DLL, um mit den neuen version der Anwendung, dies wird automatisch erledigt, da die Office-wrapper ist im Lieferumfang der Lösung. Da die Wrapper sind in der Projektmappe enthaltenen, diejenigen Erben, die APP-Version, aber wir haben es zweimal durchführen und dann "kopieren" die anderen DLL auf dem Computer, erstellt das Installationsprogramm. (Ein Schmerz...)
Frage
Ist es möglich, zu kompilieren eine DLL, die die Arbeit mit alle version der Anwendung, obwohl Sie "älter"? Ich habe etwas gelesen über manifeste, aber ich habe noch nie mit diesen interagieren. Jegliche Hinweise werden dankbar angenommen.
Den geheimen Grund dafür ist, dass wir uns nicht geändert, unser Wrapper "Alter" und auch nicht Microsoft, die mit Ihren alten APIs, aber wir werden das erneute kompilieren der DLL entsprechen, die app-version auf jeder Version, die wir machen. Ich möchte diesen Prozess zu automatisieren, anstatt verlassen sich auf zwei Maschinen.
Ich kann nicht entfernen Sie die DLL aus dem Projekt (keiner von Ihnen), weil es Abhängigkeiten.
Ich könnte einen " Dritten "master-wrapper" doch nicht etwa gedacht haben, es noch.
Irgendwelche Ideen? Jemand anderes mit der gleichen Anforderung?
UPDATE
Klären:
Habe ich 1-Lösung mit N-Projekte.
"Anwendung" + Office11Wrapper.dll + Office12Wrapper.dll.
Beide "Wrapper" benutzen Abhängigkeiten für die Anwendung + anderen Bibliotheken in der Lösung (datalayer, businesslayer, Rahmen, etc.)
Jeder wrapper verfügt über Referenzen, die für die jeweiligen Office-Paket (2003 und 2007).
Wenn ich kompilieren und nicht office 12 installiert ist, bekomme ich Fehler aus Office12Wrapper.dll nicht, dass man die Office 2007-Bibliotheken.
Also was ich habe sind zwei Gebäude, Maschinen, eine mit Office 2003, bei Office 2007. Nach einem kompletten SVN update + kompilieren auf jedem Rechner, verwenden wir nur office12.dll in der "installer", um den wrapper kompiliert gegen die "gleicher code, gleiche version".
Hinweis: Die Office-2007-Aufbau-Maschine, hat der Wrapper für Office 2003 - "entladen" - und Umgekehrt.
Vielen Dank im Voraus.
- Ich fixe den link in meiner Antwort, die Punkte zu einem MS-Artikel auf, wie zu installieren, die zwei side-by-side.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Wenn die .NET-assembly resolver ist nicht in der Lage zu finden, eine referenzierte assembly zur Laufzeit (in diesem Fall, Sie nicht finden können, die insbesondere die wrapper-DLL-version der Anwendung verknüpft wurde, gegen), seine Standard-Verhalten ist zum scheitern verurteilt und im wesentlichen zum Absturz der Anwendung. Doch dieses Verhalten kann überschrieben werden, durch Einhaken der Anwendungsdomäne.AssemblyResolve-Ereignis. Dieses Ereignis wird ausgelöst, wenn eine referenzierte assembly nicht gefunden werden kann, und es gibt Ihnen die Möglichkeit zu ersetzen, den eine andere Versammlung an die Stelle der fehlenden (sofern Sie kompatibel sind). So, zum Beispiel, könnten Sie ersetzen Sie eine ältere version der wrapper DLL, laden Sie sich.
Der beste Weg den ich gefunden habe, dies zu tun ist, fügen Sie eine statische Konstruktor für die Hauptklasse der Anwendung, die Haken der Veranstaltung, z.B.:
Indem diese in einem statischen Konstruktor der main-Anwendung Klasse, es ist garantiert ausgeführt werden, bevor irgendein code versucht, Zugriff auf alles in der wrapper-DLL, die sicherstellt, dass sich der Haken im Ort vor der Zeit.
Können Sie auch verwenden Sie policy-Dateien zu tun, version Umleitung, aber das ist eher Komplex.
Nur ein Gedanke - könnte Sie verwenden TlbExp zwei interop-Assemblys mit verschiedenen Namen und Baugruppen), und verwenden Sie eine Schnittstelle/factory code gegen die beiden über Ihre eigene Schnittstelle? Nachdem Sie die interop-dll, die Sie nicht brauchen, die COM-Abhängigkeit (außer natürlich für die Prüfung etc.).
TlbImp hat eine /asmversion für die version, es könnte also getan werden, als Teil des build-Skript; aber ich bin sicher, Sie müssen sogar diese: so stellen Sie sicher, dass "bestimmte version" ist falsch in der Referenz (Projektmappen-explorer)?
Auch - ich weiß, es hilft nicht, aber C# 4.0 mit
dynamic
und/oder "Nein PIA" helfen kann hier (in der Zukunft; vielleicht).Ich bin mir nicht sicher, ich bin komplett nach all dem, was Sie gesagt, aber lassen Sie mich versuchen:
Es klingt wie Sie haben eine Lösung mit 2(?) Projekte. Die eine ist die eigentliche Anwendung, und der andere ist ein wrapper für die Office-API. Ihre Anwendung hat dann ein Projekt-Verweis auf die Office-API-wrapper. Ich habe noch nie programmiert für office vor, aber es klingt wie Sie die Programmier-APIs sind eine gemeinsame Komponente, Sie können nur eine version auf einem Rechner (ie. 2003 oder 2007, nicht beide). Und vielleicht ist dies, wo das problem liegt, aber da haben Sie einen project-Verweis, der wrapper wird zuerst kompiliert werden, kopiert Sie ins bin-Verzeichnis Ihrer Anwendung, auf dem die Anwendung verknüpft werden, die den Aufbau der wrapper. Dies führt dazu, das manifest der Anwendung speziell anfordern, die version der wrapper zur Laufzeit.
Wenn du den wrapper eine eigene Lösung, und fügte hinzu, ein Verweis auf die kompilierte Bibliothek, anstatt das Projekt, Sie würde immer wieder verknüpfen Sie Ihre Anwendung an, die version des wrappers, und man könnte das problem vermeiden.
Eine weitere mögliche Wahl ist Assembly Binding Redirection. Dies ist weiter Fortgeschritten, und kommt mit seinen eigenen Satz von Problemen, aber man kann darüber Lesen, es hier.
Oder ähnliches zu Marc ' s Idee, Sie könnten extrahieren einer Schnittstelle, und ziehen Sie einige gemeinsame Objekte in einer Framework-Bibliothek und code-Anwendung mit der Schnittstelle und gemeinsame Objekte. Dann zur Laufzeit verwenden Sie reflektion, um die assembly zu laden und instanziieren Sie die wrapper, die Sie wollen.
Ich denke, der Schlüssel ist, um das Projekt Abhängigkeit, wenn Sie können. Es klingt wie die Hülle ist ziemlich stabil und ändert sich nicht, sonst würdest du nicht Fragen, um einen link zu einer vorherigen version.
Installation von Office 2003 und 2007 nebeneinander auf der gleichen Maschine ist auf jeden Fall möglich - wir tun es in unserer organisation auch auf end-user-Produktion Arbeitsplätze.
In diesem verlinkten Artikel von Microsoft empfehlen, dass Sie dies nicht tun für die tatsächliche Nutzung. Aber in deinem Fall erscheint es nur für einen einzelnen build-Maschine, d.h. Sie gehen nicht, um tatsächlich eine version von Office auf der Maschine. In diesem Zusammenhang würde ich versuchen, um zu sehen, ob Sie das side-by-side-installation arbeiten.
Meine Annahme falsch sein könnte, und Sie versuchen, dies zu tun für jeden Entwicklers Maschine. In diesem Fall sollten Sie ignorieren diese Antwort 🙂
Schön sleuthwork! Ich warf gerade zusammen eine Implementierung basierend auf dem oben vorgestellten Konzept, und es funktioniert wunderbar:
Natürlich gibt es Raum für Verbesserung, aber dies funktioniert der trick für mich!