Ich habe ein kleines Dilemma beim Einrichten meiner Visual Studio-Builds für Multi-Targeting.
Hintergrund: c # .NET v2.0 mit p / Aufruf in 32-Bit-DLLs von Drittanbietern, SQL compact v3.5 SP1, mit einem Setup-Projekt. Derzeit ist das Plattformziel auf x86 festgelegt, damit es unter Windows x64 ausgeführt werden kann.
Das Drittanbieterunternehmen hat gerade 64-Bit-Versionen seiner DLLs veröffentlicht, und ich möchte ein spezielles 64-Bit-Programm erstellen.
Dies wirft einige Fragen auf, auf die ich noch keine Antworten habe. Ich möchte genau die gleiche Codebasis haben. Ich muss mit Verweisen auf den 32-Bit-Satz von DLLs oder 64-Bit-DLLs bauen. (Sowohl Drittanbieter als auch SQL Server Compact)
Kann dies mit 2 neuen Konfigurationssätzen (Debug64 und Release64) gelöst werden?
Muss ich 2 separate Setup-Projekte erstellen (Standard-Visual Studio-Projekte, kein Wix oder ein anderes Dienstprogramm), oder kann dies innerhalb derselben MSI-Lösung gelöst werden?
Ideen und / oder Empfehlungen sind willkommen.
quelle
Antworten:
Ja, Sie können sowohl x86 als auch x64 mit derselben Codebasis im selben Projekt als Ziel festlegen. Im Allgemeinen funktionieren die Dinge nur, wenn Sie die richtigen Lösungskonfigurationen in VS.NET erstellen (obwohl P / Invoke für vollständig nicht verwaltete DLLs höchstwahrscheinlich einen bedingten Code erfordert): Die Elemente, für die ich besondere Aufmerksamkeit benötigte, sind:
Das Assemblyreferenzproblem kann in VS.NET nicht vollständig gelöst werden, da Sie einem Projekt nur einmal eine Referenz mit einem bestimmten Namen hinzufügen können. Um dies zu umgehen, bearbeiten Sie Ihre Projektdatei manuell (klicken Sie in VS mit der rechten Maustaste auf Ihre Projektdatei im Projektmappen-Explorer, wählen Sie Projekt entladen, klicken Sie erneut mit der rechten Maustaste und wählen Sie Bearbeiten). Nachdem Sie beispielsweise einen Verweis auf die x86-Version einer Assembly hinzugefügt haben, enthält Ihre Projektdatei Folgendes:
Wickeln Sie dieses Referenz-Tag in ein ItemGroup-Tag ein und geben Sie die Lösungskonfiguration an, für die es gilt, z.
Kopieren Sie dann das gesamte ItemGroup-Tag, fügen Sie es ein und bearbeiten Sie es so, dass es die Details Ihrer 64-Bit-DLL enthält, z.
Nach dem erneuten Laden Ihres Projekts in VS.NET wird das Dialogfeld "Assembly-Referenz" durch diese Änderungen etwas verwirrt. Möglicherweise werden einige Warnungen zu Assemblys mit dem falschen Zielprozessor angezeigt, aber alle Builds funktionieren einwandfrei.
Das MSI Problem zu lösen , ist als nächstes, und leider wird ein non-VS.NET Werkzeug benötigen: Ich ziehe es Caphyon des Advanced Installer für diesen Zweck, da es den grundlegenden Trick beteiligt (Schaffung eines gemeinsamen MSI, sowie 32-Bit zieht ab und 64-Bit-spezifische MSIs und verwenden Sie einen EXE-Setup-Launcher, um die richtige Version zu extrahieren und die erforderlichen Korrekturen zur Laufzeit durchzuführen.
Sie können wahrscheinlich die gleichen Ergebnisse mit anderen Tools oder dem Windows Installer XML (WiX) -Toolset erzielen , aber Advanced Installer macht die Dinge so einfach (und ist dabei recht erschwinglich), dass ich nie wirklich nach Alternativen gesucht habe.
Möglicherweise benötigen Sie dennoch WiX, auch wenn Sie Advanced Installer verwenden, die benutzerdefinierten Aktionen der .NET Installer-Klasse. Obwohl es trivial ist, bestimmte Aktionen anzugeben, die nur auf bestimmten Plattformen ausgeführt werden sollen (unter Verwendung der Ausführungsbedingungen VersionNT64 bzw. NOT VersionNT64), werden die integrierten benutzerdefinierten AI-Aktionen mithilfe des 32-Bit-Frameworks ausgeführt, selbst auf 64-Bit-Computern .
Dies wird möglicherweise in einer zukünftigen Version behoben, aber für den Moment (oder wenn Sie ein anderes Tool zum Erstellen Ihrer MSIs mit demselben Problem verwenden) können Sie die verwaltete benutzerdefinierte Aktionsunterstützung von WiX 3.0 verwenden, um Aktions-DLLs mit der richtigen Bitness zu erstellen wird mit dem entsprechenden Framework ausgeführt.
Bearbeiten: Ab Version 8.1.2 unterstützt Advanced Installer benutzerdefinierte 64-Bit-Aktionen korrekt. Seit meiner ursprünglichen Antwort ist der Preis leider ziemlich gestiegen, obwohl er im Vergleich zu InstallShield und seiner Art immer noch ein extrem gutes Preis-Leistungs-Verhältnis bietet ...
Bearbeiten: Wenn Ihre DLLs im GAC registriert sind, können Sie auch die Standardreferenz-Tags auf diese Weise verwenden (Beispiel SQLite):
Die Bedingung wird auch auf alle Build-Typen (Release oder Debug) reduziert und gibt lediglich die Prozessorarchitektur an.
quelle
Angenommen, Sie haben die DLLs für beide Plattformen erstellt und sie befinden sich am folgenden Speicherort:
Sie müssen lediglich Ihre .csproj-Datei wie folgt bearbeiten:
Dazu:
Sie sollten dann in der Lage sein, Ihr Projekt für beide Plattformen zu erstellen, und MSBuild sucht im richtigen Verzeichnis für die ausgewählte Plattform.
quelle
Ich bin mir nicht sicher, ob Ihre Frage vollständig beantwortet wurde. Ich dachte jedoch, ich würde auf einen Kommentar im Abschnitt "Zusätzliche Informationen" der Download-Seite von SQL Compact 3.5 SP1 hinweisen, wenn Sie x64 betrachten. Ich hoffe, es hilft.
Ich habe dies als "32-Bit-SQLCE-Dateien sowie 64-Bit-Dateien einschließen" gelesen, wenn es für 64-Bit-Clients verteilt wird.
Das macht das Leben interessant, denke ich. Ich muss sagen, dass ich die Zeile "Was scheint, sind zeitweise auftretende Probleme" liebe. Klingt ein bisschen wie "Sie stellen sich Dinge vor, aber nur für den Fall, tun Sie dies ...".
quelle
Ein .NET-Build mit x86 / x64-Abhängigkeiten
Während alle anderen Antworten Ihnen eine Lösung bieten, um je nach Plattform unterschiedliche Builds zu erstellen, gebe ich Ihnen die Option, nur die "AnyCPU" -Konfiguration zu haben und einen Build zu erstellen, der mit Ihren x86- und x64-DLLs funktioniert.
Sie müssen dafür einen Installationscode schreiben.
Auflösung der richtigen x86 / x64-DLLs zur Laufzeit
Schritte:
<ResolveAssemblyWarnOrErrorOnTargetArchitectureMismatch>None</ResolveAssemblyWarnOrErrorOnTargetArchitectureMismatch>
Fügen Sie dieses Postbuild-Skript zu Ihrem Startprojekt hinzu, verwenden und ändern Sie die Pfade dieses Skripts, damit alle Ihre x86 / x64-DLLs in die entsprechenden Unterordner Ihres Build-Bin \ x86 \ bin \ x64 \ kopiert werden
xcopy /E /H /R /Y /I /D $(SolutionDir)\YourPathToX86Dlls $(TargetDir)\x86 xcopy /E /H /R /Y /I /D $(SolutionDir)\YourPathToX64Dlls $(TargetDir)\x64
-> Wenn Sie die Anwendung jetzt starten, erhalten Sie eine Ausnahme, dass die Assembly nicht gefunden wurde.
Registrieren Sie das AssemblyResolve-Ereignis direkt am Anfang Ihres Anwendungseinstiegspunkts
mit dieser Methode:
Leistungen:
Nachteile: - Keine Fehler beim Kompilieren, wenn x86 / x64-DLLs nicht übereinstimmen. - Sie sollten trotzdem in beiden Modi testen!
Erstellen Sie optional eine zweite ausführbare Datei, die exklusiv für die x64-Architektur ist, mit Corflags.exe im Postbuild-Skript
Andere Varianten zum Ausprobieren: - Sie benötigen den AssemblyResolve-Ereignishandler nicht, wenn Sie sicherstellen, dass die richtigen DLLs beim Start in Ihren Binärordner kopiert werden (Prozessarchitektur auswerten -> entsprechende DLLs von x64 / x86 in den Bin-Ordner und zurück verschieben. ) - Bewerten Sie im Installationsprogramm die Architektur und löschen Sie Binärdateien auf falsche Architektur und verschieben Sie die richtigen in den Ordner bin.
quelle
In Bezug auf Ihre letzte Frage. Höchstwahrscheinlich können Sie dies nicht in einem einzigen MSI lösen. Wenn Sie Registrierungs- / Systemordner oder ähnliches verwenden, muss dies dem MSI selbst bekannt sein und Sie müssen ein 64-Bit-MSI für die ordnungsgemäße Installation auf einem 32-Bit-Computer vorbereiten.
Es besteht die Möglichkeit, dass Sie Ihr Produkt als 32-it-Anwendung installieren und dennoch als 64-Bit-Anwendung ausführen können, aber ich denke, dass dies etwas schwierig zu erreichen ist.
Davon abgesehen denke ich, dass Sie in der Lage sein sollten, eine einzige Codebasis für alles zu behalten. An meinem derzeitigen Arbeitsplatz haben wir das geschafft. (aber es brauchte etwas Jonglieren, um alles zusammen zu spielen)
Hoffe das hilft. Hier ist ein Link zu einigen Informationen zu 32/64-Bit-Problemen: http://blog.typemock.com/2008/07/registry-on-windows-64-bit-double-your.html
quelle
Wenn Sie in .NET geschriebene benutzerdefinierte Aktionen als Teil Ihres MSI-Installationsprogramms verwenden, liegt ein anderes Problem vor.
Der Shim, der diese benutzerdefinierten Aktionen ausführt, ist immer 32 Bit, dann wird Ihre benutzerdefinierte Aktion auch 32 Bit ausführen, unabhängig davon, welches Ziel Sie angeben.
Weitere Informationen und einige Ninja-Bewegungen, um herumzukommen (ändern Sie im Grunde das MSI, um die 64-Bit-Version dieses Shims zu verwenden).
Erstellen einer MSI in Visual Studio 2005/2008 für die Arbeit mit SharePoint 64
Verwaltete benutzerdefinierte 64-Bit-Aktionen mit Visual Studio
quelle
Sie können zwei Lösungen unterschiedlich generieren und anschließend zusammenführen! Ich habe das für VS 2010 gemacht und es funktioniert. Ich hatte 2 verschiedene Lösungen von CMake generiert und sie zusammengeführt
quelle
Sie können eine Bedingung für eine ItemGroup für die DLL-Referenzen in der Projektdatei verwenden.
Dadurch überprüft Visual Studio den Zustand und die Referenzen erneut, wenn Sie die aktive Konfiguration ändern.
Fügen Sie einfach eine Bedingung für jede Konfiguration hinzu.
Beispiel:
quelle