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:
- Verweise auf externe verwaltete Assemblys mit demselben Namen, aber ihrer eigenen spezifischen Bitness (dies gilt auch für COM-Interop-Assemblys)
- Das MSI-Paket (das, wie bereits erwähnt, entweder auf x86 oder x64 abzielen muss)
- Alle benutzerdefinierten, auf .NET Installer-Klassen basierenden Aktionen in Ihrem MSI-Paket
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:
<Reference Include="Filename, ..., processorArchitecture=x86">
<HintPath>C:\path\to\x86\DLL</HintPath>
</Reference>
Wickeln Sie dieses Referenz-Tag in ein ItemGroup-Tag ein und geben Sie die Lösungskonfiguration an, für die es gilt, z.
<ItemGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
<Reference ...>....</Reference>
</ItemGroup>
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.
<ItemGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x64' ">
<Reference Include="Filename, ..., processorArchitecture=AMD64">
<HintPath>C:\path\to\x64\DLL</HintPath>
</Reference>
</ItemGroup>
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):
<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 wird auch auf alle Build-Typen (Release oder Debug) reduziert und gibt lediglich die Prozessorarchitektur an.