2010-09-30 4 views
106

Ich habe ein Projekt, das 32/64-Bit erstellt und über entsprechende 32/64-Bit-Abhängigkeiten verfügt. Ich möchte in der Lage sein, Konfigurationen zu wechseln und die richtige Referenz verwendet zu haben, aber ich weiß nicht, wie ich Visual Studio anweisen soll, die architekturgerechte Abhängigkeit zu verwenden.Bedingte Verwendung 32/64 Bit-Referenz beim Erstellen in Visual Studio

Vielleicht gehe ich über den falschen Weg, aber ich möchte in der Konfiguration Drop-down zwischen x86 und x64 wechseln können, und die DLL DLL haben die richtige Bitness.

+0

Sehr unklar, welche Sprache ist das? Ist das DLL-Projekt in der Lösung? –

+0

Sorry, das ist .NET, ich schreibe in C#. –

+3

Ok, ich habe es mit einer dummen Lösung gelöst: Eine zusätzliche csproj-Datei erstellt, die nur auf die x64-DLL verweist (und die x86-Konfiguration aus dem csproj entfernt hat). Es funktioniert, aber wenn jemand eine elegantere Lösung hatte, die kein zusätzliches csproj beinhaltete, würde ich es gerne sehen. –

Antwort

91

Hier ist, was ich in einem früheren Projekt gemacht haben, die erfordert die manuelle Ausgabe der .csproj-Datei (en). Sie benötigen außerdem separate Verzeichnisse für die verschiedenen Binärdateien, die idealerweise gleichrangig sind und denselben Namen haben wie die Plattform, auf die Sie ausgerichtet sind.

Nachdem Sie die Referenzen einer einzelnen Plattform zum Projekt hinzugefügt haben, öffnen Sie die .csproj in einem Texteditor. Fügen Sie vor dem ersten Element <ItemGroup> innerhalb des Elements <Project> den folgenden Code hinzu, mit dessen Hilfe Sie feststellen können, auf welcher Plattform Sie arbeiten (und auf welche Sie bauen).

<!-- Properties group for Determining 64bit Architecture --> 
<PropertyGroup> 
    <CurrentPlatform>x86</CurrentPlatform> 
    <CurrentPlatform Condition="'$(PROCESSOR_ARCHITECTURE)'=='AMD64' or '$(PROCESSOR_ARCHITEW6432)'=='AMD64'">AMD64</CurrentPlatform> 
</PropertyGroup> 

Dann für Ihre Plattform spezifische Referenzen, machen Sie Änderungen wie folgt zusammen:

<ItemGroup> 
    <Reference Include="Leadtools, Version=16.5.0.0, Culture=neutral, PublicKeyToken=9cf889f53ea9b907, processorArchitecture=x86"> 
    <SpecificVersion>False</SpecificVersion> 
    <HintPath>..\..\Lib\Leadtools\$(CurrentPlatform)\Leadtools.dll</HintPath> 
    </Reference> 
    <Reference Include="Leadtools.Codecs, Version=16.5.0.0, Culture=neutral, PublicKeyToken=9cf889f53ea9b907, processorArchitecture=x86"> 
    <SpecificVersion>False</SpecificVersion> 
    <HintPath>..\..\Lib\Leadtools\$(CurrentPlatform)\Leadtools.Codecs.dll</HintPath> 
    </Reference> 
    <Reference Include="Leadtools.ImageProcessing.Core, Version=16.5.0.0, Culture=neutral, PublicKeyToken=9cf889f53ea9b907, processorArchitecture=x86"> 
    <SpecificVersion>False</SpecificVersion> 
    <HintPath>..\..\Lib\Leadtools\$(CurrentPlatform)\Leadtools.ImageProcessing.Core.dll</HintPath> 
    </Reference> 
    <Reference Include="System" /> 
    <Reference Include="System.Core" /> 
    <Reference Include="System.Data.Entity" /> 
    <!-- Other project references --> 
</ItemGroup> 

Beachten Sie die Verwendung des $(CurrentPlatform) Eigenschaft, die wir oben definiert sind. Sie können stattdessen Bedingungen verwenden, für die Baugruppen für welche Plattform enthalten sind.Man könnte muß auch entweder entweder:

  • die $(PROCESSOR_ARCHITEW6432) und $(PROCESSOR_ARCHITECTURE) mit $(Platform) nur ersetzen, die Zielplattform der Projekte, um
  • Alter der Plattform Bestimmungslogik zu prüfen, um die aktuellen Maschine angemessen zu sein, so dass Sie erstellen/referenzieren keine 64-Bit-Binärdatei, um sie auf einer 32-Bit-Plattform auszuführen.

Das hatte ich bei der Arbeit ursprünglich für einen internen Wiki geschrieben, aber ich habe es geändert und veröffentlichte die full process to my blog, wenn Sie in der ausführlichen Schritt-für-Schritt-Anleitung interessiert sind.

+1

Schön. Ich ging mit einer Bedingung für die ItemGroup wie unten vorgeschlagen, aber mit $ (PROCESSOR_ARCHITEW6432) und $ (PROCESSOR_ARCHITECTURE) für die Bedingungen wie hier. Eine Anmerkung ist, dass ich gefunden habe $ (PROCESSOR_ARCHITECTURE) gibt x86 sowohl auf 32- als auch auf 64-Bit-Plattformen zurück, aber $ (PROCESSOR_ARCHITEW6432) gibt AMD64 nur auf 64-Bit zurück. Etwas zu beachten, wenn Sie versuchen, für x86 zu testen (weil AMD64 eine Ableitung von x86 ist, nehme ich an). – tjmoore

+0

Danke für diese Informationen @tjmoore. Auf welchem ​​O/S hast du das bemerkt? Ich habe nur meine (Win7SP1) überprüft und sagt AMD64 für die $ (PROCESSOR_ARCHITECTURE), würde aber gerne so vollständige und vollständige Informationen wie möglich haben. – Hugo

+7

Komisch, meine Suche bringt mich hierher, und ich brauche das nur, weil ich auch LeadTools verwende ... +1 –

47

AFAIK, wenn Ihr Projekt erfordert Referenzen, die 32-Bit- oder 64-Bit-spezifisch (dh COM-Interop-Assembly) sind, und Sie haben kein Interesse an der CSPROJ Datei manuell bearbeiten, dann werden Sie separate erstellen müssen 32-Bit- und 64-Bit-Projekte.

Ich sollte beachten, dass die folgende Lösung nicht getestet ist, aber funktionieren sollte. Wenn Sie die .csproj-Datei manuell bearbeiten möchten, sollten Sie in der Lage sein, das gewünschte Ergebnis mit einem einzigen Projekt zu erreichen. Die .csproj-Datei ist nur ein MSBuild-Skript. Suchen Sie für eine vollständige Referenz nach here. Nachdem Sie die .csproj-Datei in einem Editor geöffnet haben, suchen Sie nach den Elementen <Reference>. Sie sollten in der Lage sein, diese Elemente in 3 verschiedene item groups zu trennen: Verweise, die nicht plattformspezifisch sind, x86-spezifische Verweise und x64-spezifische Verweise.

Hier ist ein Beispiel, dass Ihr Projekt übernimmt mit Zielplattformen namens „x86“ und „x64“

<!-- this group contains references that are not platform specific --> 
<ItemGroup> 
    <Reference Include="System" /> 
    <Reference Include="System.Core" /> 
    <!-- any other references that aren't platform specific --> 
</ItemGroup> 

<!-- x86 specific references --> 
<ItemGroup Condition=" '$(Platform)' == 'x86' "> 
    <Reference Include="MyComAssembly.Interop"> 
     <HintPath>..\..\lib\x86\MyComAssembly.Interop.dll</HintPath> 
    </Reference> 

    <!-- any additional x86 specific references --> 
</ItemGroup> 

<!-- x64 specific referneces --> 
<ItemGroup Condition=" '$(Platform)' == 'x64' "> 
    <Reference Include="MyComAssembly.Interop"> 
     <HintPath>..\..\lib\x64\MyComAssembly.Interop.dll</HintPath> 
    </Reference> 

    <!-- any additional x64 specific references --> 
</ItemGroup> 

nun konfiguriert ist, wenn Sie Ihr Projekt/Lösung Build-Konfiguration stellen Sie die x86 oder x64-Plattform zum Ziel , sollte es die richtigen Referenzen in jedem Fall enthalten. Natürlich müssen Sie mit den Elementen <Reference> spielen. Sie könnten sogar Dummy-Projekte einrichten, in denen Sie die x86- und x64-Referenzen hinzufügen und dann einfach die erforderlichen <Reference> Elemente aus diesen Dummy-Projektdateien in Ihre "echte" Projektdatei kopieren.


Edit 1
Hier ist ein Link auf die gemeinsamen Elemente MSBuild-Projekt, das ich versehentlich aus der ursprünglichen Nachricht ausgelassen: http://msdn.microsoft.com/en-us/library/bb629388.aspx

+0

Ausgezeichnete Antwort !! Habe meinen Tag gerettet! Danke vielmals. – hellodear

7

Ich verweise auf die x86-DLLs, z. \ component \ v3_NET4, in meinem Projekt. Bestimmte DLLs für x86/x64 befinden sich in Unterordnern mit den Namen "x86" bzw. "x64".

Dann verwende ich ein Pre-Build-Skript, das entsprechende DLLs (x86/x64) in den referenzierten Ordner kopiert, basierend auf $ (PlatformName).

xcopy /s /e /y "$(SolutionDir)..\component\v3_NET4\$(PlatformName)\*" "$(SolutionDir)..\component\v3_NET4" 

Funktioniert für mich.

15

Sie können eine Bedingung zu einer 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> 
+1

Das ist großartig, danke! Dies sollte definitiv die akzeptierte Lösung sein! – ManicBlowfish

+0

Im Ernst, diese Antwort ist viel besser und einfacher als die angenommene. – Yandros

+0

Ist es normal, doppelte Einträge in Referenzen zu haben? – natenho

2

konfrontiert ich das gleiche Problem und verbrachte eine ganze Weile für eine anständige Lösung zu suchen. Die meisten Leute bieten eine manuelle Bearbeitung von Visual Studio-Lösungsdateien an, was ziemlich mühsam, fehleranfällig und verwirrend ist, wenn diese bearbeiteten Dateien anschließend in Visual Studio GUI untersucht werden. Als ich bereits aufgegeben habe, kam die Lösung selbst auf. Es ist sehr ähnlich dem, was Micke in seiner Antwort oben empfiehlt.

Im Account Manager habe ich wie gewohnt zwei separate Build-Ziele für x86- und x64-Plattformen erstellt. Als Nächstes fügte ich meinem Projekt einen Verweis auf die x86-Assembly hinzu. An diesem Punkt glaubte ich, dass das Projekt nur für den x86-Build konfiguriert ist und niemals für die x64-Konfiguration erstellt wird, es sei denn, ich werde es manuell bearbeiten, wie von Hugo oben vorgeschlagen.

Nach einer Weile habe ich schließlich die Begrenzung vergessen und versehentlich x64 Build gestartet. Natürlich ist der Build fehlgeschlagen. Aber wichtig war die Fehlermeldung, die ich erhielt. Fehlermeldung, dass die Assembly, die genau wie meine referenzierte x86-Assembly benannt ist, in dem Ordner fehlt, der als x64-Buildziel für meine Lösung vorgesehen ist.

Nachdem ich dies bemerkt habe, habe ich die richtige x64 Assembly manuell in dieses Verzeichnis kopiert. Ruhm! Mein x64-Build ist auf wundersame Weise gelungen, indem die richtige Assembly implizit gefunden und verknüpft wurde. Es war eine Frage von Minuten, meine Lösung zu ändern, um ein Build-Zielverzeichnis für x64-Assembly in diesem Ordner festzulegen. Nach diesen Schritten wird die Lösung automatisch für x86 und x64 ohne manuelle Bearbeitung von MSBuild-Dateien erstellt.

Fazit:

  1. x86 und x64 Ziele in einem einzigen Projekt erstellen
  2. alle richtigen Projektreferenzen auf x86 Baugruppen hinzufügen
  3. Set ein Common-Build-Zielverzeichnis für alle x64 Baugruppen
  4. Wenn Sie bereit sind, x64-Baugruppen, kopieren Sie sie einfach einmal in Ihr x64-Build-Zielverzeichnis

Nach Abschluss dieser Schritte wird Ihre Lösung ordnungsgemäß für x86- und x64-Konfigurationen erstellt.

Dies funktionierte für mich auf Visual Studio 2010 .NET 4.0 C# -Projekt. Offensichtlich ist dies eine Art undokumentiertes internes Verhalten von Visual Studio, das sich in den Versionen 2012, 2013 und 2015 ändern könnte. Wenn jemand andere Versionen ausprobieren möchte, bitte teile deine Erfahrung mit.