Ich arbeite an einem Projekt, das conflict.dll Version 6.2 verwendet, aber das Projekt verwendet auch helper.dll, die conflict.dll Version 5.8 verwendet.
Ich könnte 6.2 und 5.8 in den GAC installieren, aber ich möchte dieses Projekt xcopy bereitstellen lassen. Ich glaube, dass .net wie folgt nach den Assemblys im Anwendungsverzeichnis suchen wird: \ bin \ konflikt.dll (6.2) \ bin \ 5.8 \ conflict.dll (5.8)
Aber an dieser Stelle, wie füge ich einen Verweis auf beide Versionen von conflict.dll im Projekt hinzu, und wie stelle ich dann sicher, dass die alte conflict.dll nach \ bin \ 5.8 implementiert? Erstelle ich eine Build-Aktion oder gibt es einen anderen Weg?
Danke
Zur Unterstützung von Darin's Antwort müssen Sie natürlich solche Probleme mit mehreren Versionen beseitigen. Seine Lösung, eine verbindliche Umleitung zu verwenden, ist eine gute - +1 dort. Ich kann eine Lösung anbieten, mit der Sie beides behalten können, wenn es absolut notwendig ist, aber Sie müssen ein wenig Code schreiben.
Das einzige wirkliche Problem, das Sie hier haben, ist, dass die beiden bereitgestellten Dateinamen identisch sein müssen, damit sie vom Loader standardmäßig übernommen werden. Du könntest wirklich entsetzlich schummeln und einfach die 5.8 dll als Conflict.exe
einsetzen, damit sie Seite an Seite Conflict.dll
(und neuer) sitzen kann und du würdest finden, dass es funktioniert.
Auch nach den Links von Darin's Antwort kommen Sie zu diesem Thema MSDN Thema auf Sondieren . Basierend auf diesem Inhalt können Sie einfach die 5.8-DLL in bin \ Content \ Content.dll bereitstellen. Wenn die Laufzeitumgebung danach sucht, wird sie automatisch in diesem Unterordner angezeigt.
Allerdings - das ist keine gute Lösung:)
BEARBEITEN - NEUE LÖSUNG
Wenn beide Versionen von Conflict.dll bereits signiert sind, haben Sie tatsächlich versucht, eine der Versionen mit einem etwas anderen Namen zu implementieren? Ich habe gerade eine Winforms-App mit zwei Assembly-Referenzen auf verschiedene Versionen derselben (signierten) Assembly eingerichtet. Dies führt zu einigen Problemen mit dem Build, da die zuletzt referenzierte Version im bin-Ordner bereitgestellt wird und die andere nicht (Sie müssen also beides manuell kopieren; eines davon entsprechend umbenennen). Dann versuche ich, die App auszuführen, die ein Meldungsfeld mit zwei konstanten Strings anzeigt. eine von jeder Version der Baugruppe. Es funktioniert absolut gut.
Laden Sie hier eine Demo herunter - mach es nicht (sonst musst du die Datei umbenennen); Öffnen Sie einfach den bin \ debug-Ordner der Formular-App und führen Sie die exe aus.
ClassLibrary1.dll und ClassLibary1vanything.dll sind v1.0.0.0 und v2.0.0.0 einer Assembly mit ansonsten demselben Namen und demselben öffentlichen Schlüssel. Trotz der Tatsache, dass classlibrary1vanything.dll den falschen Dateinamen hat, funktioniert es (wahrscheinlich, weil es signiert ist).
In der app.config habe ich einen Codebasis-Hinweis eingefügt und dachte, dass das der Grund war, warum es funktionierte (ursprünglich habe ich es als einen anderen Dateinamen bereitgestellt), aber dann habe ich es auskommentiert und es funktionierte immer noch. Die Codebasis ist wahrscheinlich am nützlichsten, wenn die Assembly in einem Unterordner oder an einem anderen Speicherort bereitgestellt werden muss.
ORIGINAL TEXT
Ich habe versucht, die zweite der genannten Optionen in diesem Support-Artikel von MS zu bekommen, aber es funktioniert scheint nicht zu wollen.
Zweifellos gibt es einen cleveren Weg, es aus der Box zu machen, aber da ich nicht schlau genug bin, es (noch) zu finden, würde ich stattdessen die dritte der Optionen, die in der oben erwähnten Unterstützung angezeigt werden, verschönern Thema und hook in das AssemblyResolve
-Ereignis der App-Domäne.
Wenn Sie Ihre eigene Konfiguration (wahrscheinlich nur in appSettings) für den vollständigen Namen der Assembly hinzufügen, die an einen anderen Dateinamen gebunden werden soll, können Sie in Ihrer AssemblyResolve-Ereignisbehandlungsroutine den Namen der Assembly abrufen, die geladen werden soll um zu sehen, ob es in deiner Konfiguration ist. Wenn dies der Fall ist, greifen Sie nach dem Speicherort und verwenden Sie Assembly.LoadFrom, um es zu laden.
Wenn Sie so etwas an Ort und Stelle haben, fügen Sie einfach einen Eintrag für den Namen der Conflict v5.8-Assembly hinzu und den Dateinamen, den die App verwenden soll.
Ich weiß nicht, welche Art von App Sie bereitstellen, aber in den win-Formularen sind die Konsolen-Apps und Dienste AppDomain.CurrentDomain.BaseDirectory
gleich dem bin-Ordner und Sie können diesen mit dem Dateinamen verbinden, den Sie laden möchten . Websites sind ein wenig komplizierter.
Sollte ein Leckerbissen sein.
Ich glaube, .net wird nach dem suchen Baugruppen in der Anwendungsablage Verzeichnis wie folgt: \ bin \ conflict.dll (6.2) \ bin \ 5.8 \ conflict.dll (5.8)
Nein, das ist falsch. Ich würde Ihnen empfehlen, diesen Artikel zu lesen, um mehr darüber zu erfahren, welche Heuristik die CLR verwendet zum Sondieren .
Da gesagt wird, können Sie nicht zwei verschiedene Versionen derselben Assembly in derselben Anwendungsdomäne laden Sie können verschiedene Versionen derselben Assembly in dieselbe Anwendungsdomäne laden, aber es ist als schlechte Praxis angesehen und sollte vermieden werden. In Ihrem Fall bedeutet dies, dass Sie auswählen müssen, welche Version der in Konflikt stehenden Assembly Sie verwenden möchten. Sie haben ein paar Möglichkeiten:
lib\
neu, um die neueste Version von app/web.config
zu verwenden (Ich werde definitiv mit dieser Version gehen, wenn ich den Quellcode für xcopy
habe). Wählen Sie die gewünschte Version von bin\Conflict
und wenden Sie eine % co_de-Datei an % in Ihrer Konfigurationsdatei. Zum Beispiel, wenn Sie die neueste Version verwenden möchten:
Dadurch wird die CLR angewiesen, die Version 6.2 von Include in Project
zu laden, wenn sie versucht, Referenzen für %code% aufzulösen. Beachten Sie, dass diese Technik nicht funktioniert, wenn die beiden Versionen stark mit verschiedenen Schlüsseln signiert sind. Offensichtlich als %code% wurde gegen Version 5.8 kompiliert, wenn Sie irgendwelche Unterschiede haben (fehlende Methoden, verschiedene Methodensignaturen), erhalten Sie eine Laufzeitausnahme beim Versuch, eine in Konflikt stehende Methode aufzurufen, also tun Sie dies nur, wenn Sie absolut sicher sind, was Sie tun .
Fazit: Egal welchen Pfad du wählst, du musst %code% im Ordner bin eine einzige Version von %code% .
habenIch arbeite an einem Projekt, das conflict.dll Version 6.2 verwendet, aber das Projekt verwendet auch helper.dll, die conflict.dll Version 5.8 verwendet.
Ich könnte 6.2 und 5.8 in den GAC installieren, aber ich möchte dieses Projekt xcopy bereitstellen lassen. Ich glaube, dass .net wie folgt nach den Assemblys im Anwendungsverzeichnis suchen wird: \ bin \ konflikt.dll (6.2) \ bin \ 5.8 \ conflict.dll (5.8)
Aber an dieser Stelle, wie füge ich einen Verweis auf beide Versionen von conflict.dll im Projekt hinzu, und wie stelle ich dann sicher, dass die alte conflict.dll nach \ bin \ 5.8 implementiert? Erstelle ich eine Build-Aktion oder gibt es einen anderen Weg?
Danke
Nach vielen Stunden des Suchens und Fluchens fand ich eine Lösung, die funktioniert und einfach und zuverlässig zu implementieren ist.
Das Problem hat wie alle anderen Antworten darauf hingewiesen, dass alle folgenden Punkte erfüllt sein müssen:
Die Lösung ist in den folgenden Schritten verfügbar:
Erstellen Sie ein Verzeichnis in Ihrem Lösungsverzeichnis, z. B. %code% with diese Hierarchie:
lib \ Konflikt \ v1 \ Conflict.dll
lib \ Konflikt \ v2 \ Conflict.dll
Fügen Sie Ihrem %code% Folgendes hinzu:
%Vor%
Fügen Sie ein Post-Build-Ereignis mit einem %code% hinzu:
xcopy $ (SolutionDir) \ lib $ (TargetDir) / Y / S
Einmal erstellen, damit die Dateien kopiert werden. Klicken Sie auf "Projekt - & gt; Alle Dateien anzeigen". Klicken Sie mit der rechten Maustaste auf %code% und machen Sie %code% (das spart Ihnen den Code). Dies ist erforderlich, damit die Dateien bereitgestellt werden, wenn Sie eine Webanwendung packen.
Fertig!
Zur Unterstützung von Darin's Antwort müssen Sie natürlich solche Probleme mit mehreren Versionen beseitigen. Seine Lösung, eine verbindliche Umleitung zu verwenden, ist eine gute - +1 dort. Ich kann eine Lösung anbieten, mit der Sie beides behalten können, wenn es absolut notwendig ist, aber Sie müssen ein wenig Code schreiben.
Das einzige wirkliche Problem, das Sie hier haben, ist, dass die beiden bereitgestellten Dateinamen identisch sein müssen, damit sie vom Loader standardmäßig übernommen werden. Du könntest wirklich entsetzlich schummeln und einfach die 5.8 dll als %code% einsetzen, damit sie Seite an Seite %code% (und neuer) sitzen kann und du würdest finden, dass es funktioniert.
Auch nach den Links von Darin's Antwort kommen Sie zu diesem Thema MSDN Thema auf Sondieren . Basierend auf diesem Inhalt können Sie einfach die 5.8-DLL in bin \ Content \ Content.dll bereitstellen. Wenn die Laufzeitumgebung danach sucht, wird sie automatisch in diesem Unterordner angezeigt.
Allerdings - das ist keine gute Lösung:)
BEARBEITEN - NEUE LÖSUNG
Wenn beide Versionen von Conflict.dll bereits signiert sind, haben Sie tatsächlich versucht, eine der Versionen mit einem etwas anderen Namen zu implementieren? Ich habe gerade eine Winforms-App mit zwei Assembly-Referenzen auf verschiedene Versionen derselben (signierten) Assembly eingerichtet. Dies führt zu einigen Problemen mit dem Build, da die zuletzt referenzierte Version im bin-Ordner bereitgestellt wird und die andere nicht (Sie müssen also beides manuell kopieren; eines davon entsprechend umbenennen). Dann versuche ich, die App auszuführen, die ein Meldungsfeld mit zwei konstanten Strings anzeigt. eine von jeder Version der Baugruppe. Es funktioniert absolut gut.
Laden Sie hier eine Demo herunter - mach es nicht (sonst musst du die Datei umbenennen); Öffnen Sie einfach den bin \ debug-Ordner der Formular-App und führen Sie die exe aus.
ClassLibrary1.dll und ClassLibary1vanything.dll sind v1.0.0.0 und v2.0.0.0 einer Assembly mit ansonsten demselben Namen und demselben öffentlichen Schlüssel. Trotz der Tatsache, dass classlibrary1vanything.dll den falschen Dateinamen hat, funktioniert es (wahrscheinlich, weil es signiert ist).
In der app.config habe ich einen Codebasis-Hinweis eingefügt und dachte, dass das der Grund war, warum es funktionierte (ursprünglich habe ich es als einen anderen Dateinamen bereitgestellt), aber dann habe ich es auskommentiert und es funktionierte immer noch. Die Codebasis ist wahrscheinlich am nützlichsten, wenn die Assembly in einem Unterordner oder an einem anderen Speicherort bereitgestellt werden muss.
ORIGINAL TEXT
Ich habe versucht, die zweite der genannten Optionen in diesem Support-Artikel von MS zu bekommen, aber es funktioniert scheint nicht zu wollen.
Zweifellos gibt es einen cleveren Weg, es aus der Box zu machen, aber da ich nicht schlau genug bin, es (noch) zu finden, würde ich stattdessen die dritte der Optionen, die in der oben erwähnten Unterstützung angezeigt werden, verschönern Thema und hook in das %code% -Ereignis der App-Domäne.
Wenn Sie Ihre eigene Konfiguration (wahrscheinlich nur in appSettings) für den vollständigen Namen der Assembly hinzufügen, die an einen anderen Dateinamen gebunden werden soll, können Sie in Ihrer AssemblyResolve-Ereignisbehandlungsroutine den Namen der Assembly abrufen, die geladen werden soll um zu sehen, ob es in deiner Konfiguration ist. Wenn dies der Fall ist, greifen Sie nach dem Speicherort und verwenden Sie Assembly.LoadFrom, um es zu laden.
Wenn Sie so etwas an Ort und Stelle haben, fügen Sie einfach einen Eintrag für den Namen der Conflict v5.8-Assembly hinzu und den Dateinamen, den die App verwenden soll.
Ich weiß nicht, welche Art von App Sie bereitstellen, aber in den win-Formularen sind die Konsolen-Apps und Dienste %code% gleich dem bin-Ordner und Sie können diesen mit dem Dateinamen verbinden, den Sie laden möchten . Websites sind ein wenig komplizierter.
Sollte ein Leckerbissen sein.
Ich glaube, .net wird nach dem suchen Baugruppen in der Anwendungsablage Verzeichnis wie folgt: \ bin \ conflict.dll (6.2) \ bin \ 5.8 \ conflict.dll (5.8)
Nein, das ist falsch. Ich würde Ihnen empfehlen, diesen Artikel zu lesen, um mehr darüber zu erfahren, welche Heuristik die CLR verwendet zum Sondieren .
Da gesagt wird, können Sie nicht zwei verschiedene Versionen derselben Assembly in derselben Anwendungsdomäne laden Sie können verschiedene Versionen derselben Assembly in dieselbe Anwendungsdomäne laden, aber es ist als schlechte Praxis angesehen und sollte vermieden werden. In Ihrem Fall bedeutet dies, dass Sie auswählen müssen, welche Version der in Konflikt stehenden Assembly Sie verwenden möchten. Sie haben ein paar Möglichkeiten:
helper.dll
neu, um die neueste Version von conflict.dll
zu verwenden (Ich werde definitiv mit dieser Version gehen, wenn ich den Quellcode für helper.dll
habe). Wählen Sie die gewünschte Version von conflict.dll
und wenden Sie eine % co_de-Datei an % in Ihrer Konfigurationsdatei. Zum Beispiel, wenn Sie die neueste Version verwenden möchten:
Dadurch wird die CLR angewiesen, die Version 6.2 von <bindingRedirect>
zu laden, wenn sie versucht, Referenzen für conflict.dll
aufzulösen. Beachten Sie, dass diese Technik nicht funktioniert, wenn die beiden Versionen stark mit verschiedenen Schlüsseln signiert sind. Offensichtlich als helper.dll
wurde gegen Version 5.8 kompiliert, wenn Sie irgendwelche Unterschiede haben (fehlende Methoden, verschiedene Methodensignaturen), erhalten Sie eine Laufzeitausnahme beim Versuch, eine in Konflikt stehende Methode aufzurufen, also tun Sie dies nur, wenn Sie absolut sicher sind, was Sie tun .
Fazit: Egal welchen Pfad du wählst, du musst helper.dll
im Ordner bin eine einzige Version von xcopy
.
Tags und Links .net visual-studio assemblies