2008-09-28 8 views
103

Ich habe ein kleines Dilemma, wie ich meine Visual Studio Builds für Multi-Targeting einrichten.Targeting sowohl 32bit und 64bit mit Visual Studio in der gleichen Lösung/Projekt

Hintergrund: C# .NET v2.0 mit p/Aufruf in 32-Bit-DLLs von Drittanbietern, SQL Compact v3.5 SP1, mit einem Setup-Projekt. Momentan ist das Plattformziel auf x86 festgelegt, sodass es unter Windows x64 ausgeführt werden kann.

Das 3rd-Party-Unternehmen hat gerade 64-Bit-Versionen ihrer DLLs veröffentlicht und ich möchte ein dediziertes 64-Bit-Programm erstellen.

Dies wirft einige Fragen auf, auf die ich noch keine Antworten habe. Ich möchte die exakt gleiche Code-Basis haben. Ich muss mit Verweisen entweder auf den 32-Bit-Satz von DLLs oder 64-Bit-DLLs bauen. (3rd Party und SQL Server Compact)

Kann dies mit 2 neuen Konfigurationen (Debug64 und Release64) gelöst werden?

Muss ich 2 separate Setup-Projekte (Std. Visual Studio-Projekte, keine Wix oder andere Dienstprogramm), oder kann dies innerhalb der gleichen .msi gelöst werden?

Alle Ideen und/oder Empfehlungen wären willkommen.

+0

@Magnus Johansson: Sie zwei Konfigurationen verwenden können, die Hälfte Ihr Ziel zu erreichen. Das MSI ist ein bisschen schwieriger. – user7116

Antwort

80

Ja, können Sie sowohl die x86 und x64 mit der gleichen Code-Basis im selben Projekt zielen. Im Allgemeinen funktionieren die Dinge nur dann, wenn Sie die richtigen Lösungskonfigurationen in VS.NET erstellen (obwohl P/Invoke für vollständig nicht verwaltete DLLs höchstwahrscheinlich bedingten Code erfordern wird): Die Elemente, die ich als besondere Aufmerksamkeit benötige, sind:

  • Verweise auf außerhalb verwalteten Assemblys mit demselben Namen, aber ihre eigenen spezifischen Bitness (dies gilt auch für COM-Interop Assemblies)
  • Das MSI-Paket (die, wie bereits erwähnt wurde, entweder x86 oder x64 Ziel muß)
  • Alle benutzerdefinierten .NET Installer-klassenbasierten Aktionen in Ihrem MSI-Paket

Das Assemblyreferenzproblem kann nicht vollständig innerhalb von VS.NET gelöst werden, da Sie nur einmal einen Verweis mit einem bestimmten Namen zu einem Projekt hinzufügen können. Um dies zu umgehen, bearbeiten Sie Ihre Projektdatei manuell (in VS klicken Sie 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). Nach der Zugabe wird eine Referenz auf, sagen wir, die x86-Version einer Assembly, die Projektdatei so etwas wie enthalten:

<Reference Include="Filename, ..., processorArchitecture=x86"> 
    <HintPath>C:\path\to\x86\DLL</HintPath> 
</Reference> 

Wrap, das Tag innerhalb einer ItemGroup Tag, welche die Lösungskonfiguration es gilt, zB Referenz:

<ItemGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' "> 
    <Reference ...>....</Reference> 
</ItemGroup> 

Dann kopieren und den gesamten ItemGroup Tag einfügen und bearbeiten sie die Details Ihrer 64-Bit-DLL enthalten, zB:

<ItemGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x64' "> 
    <Reference Include="Filename, ..., processorArchitecture=AMD64"> 
    <HintPath>C:\path\to\x64\DLL</HintPath> 
    </Reference> 
</ItemGroup> 

nach dem proje Nachladen In VS.NET wird das Assembly-Referenzdialogfeld durch diese Änderungen etwas verwirrt, und Sie können einige Warnungen über Assemblys mit dem falschen Zielprozessor erhalten, aber alle Ihre Builds funktionieren einwandfrei.

die MSI-Ausgabe zu lösen, ist weiter nach oben, und leider wird benötigt ein non-VS.NET Werkzeug: Ich ziehe es Advanced Installer die Caphyon für diesen Zweck, da es den grundlegenden Trick beteiligt (Schaffung eines gemeinsamen MSI zieht ab, wie sowie 32-Bit und 64-Bit spezifische MSIs, und verwenden Sie ein .EXE-Setup-Launcher, um die richtige Version zu extrahieren und die erforderlichen Korrekturen zur Laufzeit durchzuführen) sehr, sehr gut.

Sie können wahrscheinlich die gleichen Ergebnisse mit anderen Tools oder der Windows Installer XML (WiX) toolset erreichen, aber Advanced Installer macht die Dinge so einfach (und ist ziemlich erschwinglich), dass ich nie wirklich auf Alternativen geschaut habe.

Eine Sache, die Sie Mai immer noch benötigen WiX für obwohl, selbst wenn Sie Advanced Installer verwenden, ist für Ihre .NET Installer Class benutzerdefinierte Aktionen.Es ist zwar trivial, bestimmte Aktionen anzugeben, die nur auf bestimmten Plattformen ausgeführt werden sollten (unter Verwendung der Ausführungsbedingungen VersionNT64 und NOT VersionNT64). Die integrierten benutzerdefinierten AI-Aktionen werden jedoch auch auf 64-Bit-Computern mit dem 32-Bit-Framework ausgeführt .

Dies kann in einer zukünftigen Version behoben werden, aber vorerst (oder wenn Sie ein anderes Tool zum Erstellen Ihrer MSIs mit demselben Problem verwenden) können Sie die verwaltete benutzerdefinierte Aktion von WiX 3.0 verwenden, um Aktions-DLLs mit zu erstellen die richtige Bitness, die mit dem entsprechenden Framework ausgeführt wird.


Bearbeiten: ab Version 8.1.2 unterstützt Advanced Installer 64-Bit-benutzerdefinierte Aktionen ordnungsgemäß. Seit meiner ersten Antwort hat ihr Preis erhöht ziemlich viel, leider, obwohl es immer noch ein sehr guter Preis ist im Vergleich zu Installshield und seinen ilk ...


Edit: Wenn Sie Ihre DLLs im GAC registriert sind, Sie können auch die Standard-Referenz-Tags auf diese Weise (SQLite als Beispiel) verwenden:

<ItemGroup Condition="'$(Platform)' == 'x86'"> 
    <Reference Include="System.Data.SQLite, Version=1.0.80.0, Culture=neutral, PublicKeyToken=db937bc2d44ff139, processorArchitecture=x86" /> 
</ItemGroup> 
<ItemGroup Condition="'$(Platform)' == 'x64'"> 
    <Reference Include="System.Data.SQLite, Version=1.0.80.0, Culture=neutral, PublicKeyToken=db937bc2d44ff139, processorArchitecture=AMD64" /> 
</ItemGroup> 

die Bedingung auch für alle nach unten reduziert bauen Typen, Freigabe oder debuggen und gibt nur die Prozessorarchitektur.

+0

In Visual Studio 2008 habe ich festgestellt, dass s nicht verschachtelt werden konnte. Diese Lösung hat gut funktioniert, sobald ich die neue s unter der Gruppe den Rest der s gemacht habe. Ich musste auch x86 in AnyCPU ändern, was wahrscheinlich mit der Geschichte meines speziellen Projekts zusammenhängt. –

+0

Das Advanced Installer sieht ziemlich toll aus. – Pat

+0

Das mag eine dumme Frage sein, aber wie kommt man zu der Datei, um sie manuell zu bearbeiten? – hrh

1

Nicht sicher von der Gesamtantwort auf Ihre Frage - aber ich dachte, ich würde einen Kommentar im Abschnitt Zusätzliche Informationen der SQL Compact 3.5 SP1 download page Sie sehen x64 sehen - hoffe, es hilft.

Aufgrund von Änderungen in SQL Server Compact SP1 und zusätzliche 64-Bit-Version Unterstützung, zentral installiert und gemischten Modus Umgebungen von 32-Bit-Version von SQL Server Compact 3.5 und 64-Bit- Version von SQL Server Compact 3.5 SP1 kann verursachen, was scheint intermittierende Probleme sein. das Potenzial für Konflikte zu minimieren und plattformneutrale Bereitstellung verwalteter Client-Anwendungen zu ermöglichen, zentral die 64-Bit-Version von SQL Server Compact 3.5 SP1 Installation der Windows Installer (MSI) Datei auch verwendet, erfordert die Installation 32-Bit-Version von SQL Server Compact 3.5 SP1 MSI Datei. Für Anwendungen, die nur erfordern native 64-Bit, private Bereitstellung der 64-Bit-Version von SQL Server Compact 3.5 SP1 kann verwendet werden.

Ich las dies als „die 32-Bit-Dateien SQLCE sowie die 64-Bit-Dateien enthalten“, wenn für 64-Bit-Clients zu verteilen.

Macht das Leben interessant Ich denke .. muss sagen, dass ich liebe die "was scheint, Probleme mit Unterbrechungen zu sein" ... klingt ein bisschen wie "Sie stellen sich Dinge vor, aber nur für den Fall, tu dies ..."

0

In Bezug auf Ihre letzte Frage. Höchstwahrscheinlich können Sie das in einem einzelnen MSI nicht lösen. Wenn Sie Registrierungs-/Systemordner oder etwas Ähnliches verwenden, muss das MSI selbst dies beachten und Sie müssen ein 64-Bit-MSI für die ordnungsgemäße Installation auf einem 32-Bit-Computer vorbereiten.

Es gibt eine Möglichkeit, dass Sie Ihr Produkt als 32 it-Anwendung installiert und immer noch in der Lage, es als 64-Bit-One laufen zu lassen, aber ich denke, das kann etwas schwer zu erreichen sein.

dass gesagt, ich denke, Sie sollten in der Lage sein, eine einzige Code-Basis für alles zu halten. An meinem jetzigen Arbeitsplatz haben wir es geschafft. (aber es brauchte ein wenig Jonglieren, um alles zusammen spielen zu lassen)

Hoffe, das hilft. Heres ein Link zu einem paar Informationen zu 32/64 Bit Fragen im Zusammenhang: http://blog.typemock.com/2008/07/registry-on-windows-64-bit-double-your.html

26

Angenommen, Sie haben die DLLs bauen für beide Plattformen, und sie sind in der folgenden Position:

C:\whatever\x86\whatever.dll 
C:\whatever\x64\whatever.dll 

Sie einfach Ihre CSPROJ Datei aus dieser bearbeiten müssen:

<HintPath>C:\whatever\x86\whatever.dll</HintPath> 

zu dies:

<HintPath>C:\whatever\$(Platform)\whatever.dll</HintPath> 

Sie sollten dann in der Lage sein, Ihr Projekt für beide Plattformen und MSB zu erstellen uild sucht im richtigen Verzeichnis nach der gewählten Plattform.

+0

Das wäre brillant, wenn es funktioniert, aber es nicht. Zumindest nicht für mich. –

+10

Soll das nicht sein: C: \ washer \ $ (Plattform) \ was.dll Andreas

+1

das hat Wunder für mich bewirkt, danke ein Bündel! –

0

Wenn Sie benutzerdefinierte Aktionen verwenden, die in .NET als Teil Ihres MSI-Installationsprogramms geschrieben wurden, haben Sie ein anderes Problem.

Die 'Shim', die diese benutzerdefinierten Aktionen ausführt, ist immer 32bit, dann wird Ihre benutzerdefinierte Aktion auch 32bit ausführen, trotz welches Ziel Sie angeben.

Mehr Infos & einige ninja bewegt sich herum zu erhalten (im Grunde das MSI ändern, um die 64-Bit-Version dieses Shim verwenden)

Building an MSI in Visual Studio 2005/2008 to work on a SharePoint 64

64-bit Managed Custom Actions with Visual Studio

0

Sie können zwei Lösungen anders erzeugen und fusionieren sie danach! Ich habe das für VS 2010. und es funktioniert. Ich hatte 2 verschiedene Lösungen von CMake generiert und ich fusionierte sie

0

Sie können eine Bedingung zu einem ItemGroup für die DLL-Referenzen in der Projektdatei verwenden.
Dies führt dazu, dass Visual Studio die Bedingung und Referenzen erneut überprüft, wenn Sie die aktive Konfiguration ändern.
Fügen Sie einfach eine Bedingung für jede Konfiguration hinzu.

Beispiel:

<ItemGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' "> 
    <Reference Include="DLLName"> 
     <HintPath>..\DLLName.dll</HintPath> 
    </Reference> 
    <ProjectReference Include="..\MyOtherProject.vcxproj"> 
     <Project>{AAAAAA-000000-BBBB-CCCC-TTTTTTTTTT}</Project> 
     <Name>MyOtherProject</Name> 
    </ProjectReference> 
    </ItemGroup> 
Verwandte Themen