Oui, vous pouvez cibler à la fois x86 et x64 avec la même base de code dans le même projet. En général, les choses fonctionneront simplement si vous créez les bonnes configurations de solution dans VS.NET (bien que P / Invoke pour des DLL entièrement non gérées nécessitera probablement du code conditionnel): les éléments qui nécessitent une attention particulière sont:
- Références à des assemblys gérés externes avec le même nom mais leur propre bitness spécifique (cela s'applique également aux assemblys d'interopérabilité COM)
- Le package MSI (qui, comme cela a déjà été noté, devra cibler x86 ou x64)
- Toutes les actions personnalisées basées sur les classes du programme d'installation .NET dans votre package MSI
Le problème de référence d'assembly ne peut pas être résolu entièrement dans VS.NET, car il ne vous permettra d'ajouter une référence avec un nom donné à un projet qu'une seule fois. Pour contourner ce problème, modifiez manuellement votre fichier de projet (dans VS, cliquez avec le bouton droit sur votre fichier de projet dans l'Explorateur de solutions, sélectionnez Décharger le projet, puis cliquez à nouveau avec le bouton droit et sélectionnez Modifier). Après avoir ajouté une référence à, par exemple, la version x86 d'un assembly, votre fichier projet contiendra quelque chose comme:
<Reference Include="Filename, ..., processorArchitecture=x86">
<HintPath>C:\path\to\x86\DLL</HintPath>
</Reference>
Enveloppez cette balise Reference dans une balise ItemGroup indiquant la configuration de la solution à laquelle elle s'applique, par exemple:
<ItemGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
<Reference ...>....</Reference>
</ItemGroup>
Ensuite, copiez et collez la balise ItemGroup entière, et modifiez-la pour qu'elle contienne les détails de votre DLL 64 bits, par exemple:
<ItemGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x64' ">
<Reference Include="Filename, ..., processorArchitecture=AMD64">
<HintPath>C:\path\to\x64\DLL</HintPath>
</Reference>
</ItemGroup>
Après avoir rechargé votre projet dans VS.NET, la boîte de dialogue Référence d'assemblage sera un peu confuse par ces modifications et vous risquez de rencontrer des avertissements concernant les assemblys avec le mauvais processeur cible, mais toutes vos versions fonctionneront très bien.
Résoudre le problème MSI est à côté, et malheureusement , ce sera besoin d' un outil non-VS.NET: Je préfère de Caphyon Advanced Installer à cet effet, car il retire l'astuce de base impliqués (créer un MSI commun, ainsi que 32 bits et les MSI spécifiques 64 bits, et utilisez un lanceur d'installation .EXE pour extraire la bonne version et effectuer les corrections nécessaires au moment de l'exécution) très, très bien.
Vous pouvez probablement obtenir les mêmes résultats en utilisant d'autres outils ou l'ensemble d'outils Windows Installer XML (WiX) , mais Advanced Installer rend les choses si faciles (et est tout à fait abordable à cela) que je n'ai jamais vraiment envisagé d'alternatives.
Une chose pour laquelle vous pouvez toujours avoir besoin de WiX, même lorsque vous utilisez Advanced Installer, est pour vos actions personnalisées .NET Installer Class. Bien qu'il soit trivial de spécifier certaines actions qui ne devraient s'exécuter que sur certaines plates-formes (en utilisant respectivement les conditions d'exécution VersionNT64 et NOT VersionNT64), les actions personnalisées AI intégrées seront exécutées à l'aide du Framework 32 bits, même sur des machines 64 bits .
Cela peut être corrigé dans une version ultérieure, mais pour le moment (ou lorsque vous utilisez un outil différent pour créer vos MSI qui présente le même problème), vous pouvez utiliser la prise en charge des actions personnalisées gérées par WiX 3.0 pour créer des DLL d'action avec le bon bitness qui sera exécuté en utilisant le Framework correspondant.
Edit: à partir de la version 8.1.2, Advanced Installer prend correctement en charge les actions personnalisées 64 bits. Depuis ma réponse initiale, son prix a augmenté un peu, malheureusement, même s'il est toujours extrêmement bon rapport qualité-prix par rapport à InstallShield et ses semblables ...
Edit: Si vos DLL sont enregistrées dans le GAC, vous pouvez également utiliser les balises de référence standard de cette façon (SQLite par exemple):
<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>
La condition est également réduite à tous les types de build, version ou débogage, et spécifie simplement l'architecture du processeur.