111 votes

Cibler à la fois 32bit et 64bit avec Visual Studio dans la même solution/le même projet

J'ai un petit dilemme sur la façon de configurer mes constructions Visual Studio pour le multi-ciblage.

Contexte : c# .NET v2.0 avec p/invoking into 3rd party 32 bit DLL's, SQL compact v3.5 SP1, avec un projet Setup. Pour l'instant, la cible de la plate-forme est définie sur x86 afin qu'elle puisse être exécutée sur Windows x64.

La société tierce vient de publier des versions 64 bits de ses DLL et je veux créer un programme dédié à 64 bits.

Cela soulève quelques questions auxquelles je n'ai pas encore trouvé de réponse. Je veux avoir exactement la même base de code. Je dois construire avec des références soit à l'ensemble des DLL 32 bits, soit aux DLL 64 bits. (aussi bien celles des tiers que celles de SQL Server Compact)

Est-ce que cela peut être résolu avec deux nouveaux jeux de configurations (Debug64 et Release64) ?

Dois-je créer deux projets d'installation distincts (projets standard de Visual Studio, sans Wix ou autre utilitaire), ou cela peut-il être résolu dans le même fichier .msi ?

Toute idée et/ou recommandation serait la bienvenue.

0 votes

@Magnus Johansson : vous pouvez utiliser deux configurations pour atteindre la moitié de votre objectif. Le MSI est un peu plus difficile.

83voto

mdb Points 20629

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 si vous créez les bonnes configurations de solution dans VS.NET (bien que P/Invoke vers des DLLs entièrement non gérées nécessitera très probablement du code conditionnel) : les éléments qui, selon moi, nécessitent une attention particulière sont les suivants :

  • Références à des assemblages gérés externes portant le même nom mais ayant leur propre bitness spécifique (ceci s'applique également aux assemblages COM interop).
  • Le paquet MSI (qui, comme on l'a déjà noté, devra cibler soit x86 soit x64)
  • Toute action personnalisée basée sur la classe d'installation .NET dans votre paquet MSI.

Le problème des références d'assemblage ne peut pas être résolu entièrement dans VS.NET, car il ne vous permet d'ajouter une référence avec un nom donné à un projet qu'une seule fois. Pour contourner ce problème, modifiez votre fichier de projet manuellement (dans VS, cliquez avec le bouton droit de la souris sur votre fichier de projet dans l'explorateur de solutions, sélectionnez Décharger le projet, puis cliquez à nouveau avec le bouton droit de la souris et sélectionnez Modifier). Après avoir ajouté une référence à, disons, la version x86 d'un assemblage, votre fichier de projet contiendra quelque chose comme :

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

Enveloppez cette balise de référence dans une balise ItemGroup indiquant la configuration de la solution à laquelle elle s'applique, par ex :

<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 changements, et vous pourrez rencontrer quelques avertissements concernant des assemblages avec le mauvais processeur cible, mais toutes vos constructions fonctionneront parfaitement.

Résoudre le problème MSI est le suivant, et malheureusement ceci sera nécessitent un outil non-VS.NET : Je préfère celui de Caphyon Installateur avancé à cette fin, car il réussit très bien l'astuce de base (créer un MSI commun, ainsi que des MSI spécifiques 32 et 64 bits, et utiliser un lanceur d'installation .EXE pour extraire la bonne version et effectuer les corrections nécessaires au moment de l'exécution).

Vous pouvez probablement obtenir les mêmes résultats à l'aide d'autres outils ou de l'outil de gestion de l'environnement. Outils Windows Installer XML (WiX) Mais Advanced Installer rend les choses si faciles (et est très abordable en plus) que je n'ai jamais vraiment regardé les alternatives.

Une chose que vous mai Les actions personnalisées de votre classe d'installation .NET constituent l'une des raisons pour lesquelles vous avez toujours besoin de WiX, même si vous utilisez Advanced Installer. Bien qu'il soit facile de spécifier certaines actions qui ne doivent être exécutées que sur certaines plates-formes (en utilisant les conditions d'exécution VersionNT64 et NOT VersionNT64, respectivement), les actions personnalisées AI intégrées seront exécutées en utilisant le Framework 32 bits, même sur les machines 64 bits.

Ce problème sera peut-être corrigé dans une prochaine version, mais pour l'instant (ou si vous utilisez un autre outil pour créer vos MSI qui a le même problème), vous pouvez utiliser le support des actions personnalisées gérées de WiX 3.0 pour créer des DLL d'action avec le bitness approprié qui seront exécutées en utilisant le Framework correspondant.


Edition : à 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 malheureusement beaucoup augmenté, même s'il reste extrêmement avantageux par rapport à InstallShield et ses semblables...


Edit : Si vos DLLs 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 construction, release ou debug, et spécifie seulement l'architecture du processeur.

0 votes

Dans Visual Studio 2008, j'ai constaté que les <ItemGroup> ne pouvaient pas être imbriqués. Cette solution a bien fonctionné une fois que j'ai fait les nouveaux <ItemGroup>s sous le groupe le reste des <Reference>s. J'ai également dû changer x86 en AnyCPU, ce qui est probablement lié à l'histoire de mon projet particulier.

0 votes

Cet Advanced Installer a l'air plutôt génial.

0 votes

C'est peut-être une question stupide mais comment accéder au fichier pour le modifier manuellement ?

27voto

Tim Booker Points 2243

Disons que vous avez construit les DLL pour les deux plates-formes, et qu'elles se trouvent à l'emplacement suivant :

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

Il vous suffit de modifier votre fichier .csproj à partir de celui-ci :

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

A ceci :

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

Vous devriez alors pouvoir construire votre projet en ciblant les deux plateformes, et MSBuild cherchera dans le répertoire correct pour la plateforme choisie.

0 votes

Ce serait génial si ça marchait, mais ça ne marche pas. Du moins, pas pour moi.

10 votes

Ce n'est pas censé être : <HintPath> C:\whatever\ (Plate-forme) \whatever.dll </HintPath>

0 votes

Cela a fonctionné correctement sur Visual Studio 2008 pour moi, mais n'a pas copié automatiquement la DLL dans le répertoire cible de la construction, comme le fait une <Référence> normale. La solution de mdb a mieux fonctionné pour moi.

1voto

gleng Points 338

Je ne suis pas sûr de la réponse totale à votre question, mais j'ai pensé que je pourrais vous signaler un commentaire dans la section Informations complémentaires du site Web de la Commission européenne. Page de téléchargement de SQL Compact 3.5 SP1 en voyant que vous êtes à la recherche de x64 - j'espère que cela vous aidera.

En raison des modifications apportées à SQL Server Compact SP1 et de la prise en charge de la version 64 bits 64 bits, les environnements en mode mixte et de la version 32 bits de SQL Server Compact 3.5 et 64-bit de la version 64 bits de SQL Server Compact 3.5 SP1 peuvent créer ce qui semble être problèmes intermittents. Pour minimiser le potentiel de conflits, et pour permettre et de permettre un déploiement neutre des applications client gérées, l'installation l'installation centralisée de la version 64 bits de SQL Server Compact 3.5 SP1 en utilisant le programme fichier Windows Installer (MSI) nécessite également nécessite également l'installation de la version 32 bits 32 bits de SQL Server Compact 3.5 SP1. 32 bits. Pour les applications qui ne nécessitent une version native 64 bits, le déploiement privé de la version 64 bits de SQL Server Compact 3.5 SP1 peut être utilisée.

J'ai lu ceci comme "inclure les fichiers SQLCE 32bit". ainsi que les fichiers 64 bits" si vous distribuez pour des clients 64 bits.

La vie est intéressante, je suppose... Je dois dire que j'adore la phrase "ce qui semble être des problèmes intermittents"... ça ressemble un peu à "vous imaginez des choses, mais juste au cas où, faites ceci...".

0voto

Lior Friedman Points 31

En ce qui concerne votre dernière question. Il est fort probable que vous ne puissiez pas résoudre ce problème dans un seul MSI. Si vous utilisez des dossiers de registre/système ou quoi que ce soit d'autre, le MSI lui-même doit en être conscient et vous devez préparer un MSI 64 bits pour l'installer correctement sur une machine 32 bits.

Il est possible de faire en sorte que votre produit soit installé en tant qu'application 32 bits tout en étant capable de le faire fonctionner en tant qu'application 64 bits, mais je pense que cela peut être difficile à réaliser.

Cela dit, je pense que vous devriez pouvoir conserver une base de code unique pour tout. Dans mon lieu de travail actuel, nous avons réussi à le faire. (mais il a fallu jongler pour que tout fonctionne ensemble).

J'espère que cela vous aidera. Voici un lien vers des informations relatives aux problèmes de 32/64 bits : http://blog.typemock.com/2008/07/registry-on-Windows-64-bit-double-your.html

0voto

Ryan Points 11565

Si vous utilisez des actions personnalisées écrites en .NET dans le cadre de votre installateur MSI, vous avez un autre problème.

Le "shim" qui exécute ces actions personnalisées est toujours en 32 bits, alors votre action personnalisée fonctionnera également en 32 bits, quelle que soit la cible que vous spécifiez.

Plus d'informations et quelques manœuvres ninja pour contourner le problème (changer le MSI pour utiliser la version 64 bits de cette cale).

Création d'un MSI dans Visual Studio 2005/2008 pour travailler sur un SharePoint 64

Actions personnalisées gérées en 64 bits avec Visual Studio

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X