Question

J'ai un petit dilemme sur la manière de configurer mes versions de Visual Studio pour le ciblage multiple.

Arrière-plan: c # .NET v2.0 avec p / appelant dans des DLL 32 bits tierces, SQL compact v3.5 SP1, avec un projet de configuration. Pour le moment, la cible de la plate-forme est définie sur x86 pour pouvoir être exécutée sous Windows x64.

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

Cela soulève des questions auxquelles je n’ai pas encore de réponse. Je veux avoir exactement la même base de code. Je dois construire avec des références à l'ensemble 32 bits de DLL ou aux DLL 64 bits. (Tiers et SQL Server Compact)

Peut-on résoudre ce problème avec 2 nouveaux ensembles de configurations (Debug64 et Release64)?

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

Toutes les idées et / ou recommandations seraient les bienvenues.

Était-ce utile?

La solution

Oui, vous pouvez cibler x86 et x64 avec la même base de code dans le même projet. En général, les choses fonctionneront correctement 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 très probablement un code conditionnel): les éléments qui, selon moi, requièrent une attention particulière sont:

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

Le problème de référence d'assemblage ne peut pas être entièrement résolu dans VS.NET, car il ne vous permettra d'ajouter une référence à un projet qu'une seule fois. Pour contourner ce problème, modifiez manuellement votre fichier de projet (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 à, par exemple, 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 Reference dans une balise ItemGroup en indiquant la configuration de la solution à laquelle elle s'applique, par exemple:

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

Copiez et collez ensuite l'intégralité de la balise ItemGroup, puis 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 de l'assemblage sera un peu déroutante face à ces modifications. Des avertissements concernant les assemblages avec le mauvais processeur cible risquent de se produire, mais toutes vos versions fonctionneront correctement.

La résolution du problème MSI est la suivante, et malheureusement, cela nécessitera un outil non-VS.NET: je préfère le logiciel de Caphyon Advanced Installer à cette fin, car il met en pratique l’astuce de base (créer un MSI commun, ainsi que des MSI spécifiques 32 bits et 64 bits, et utiliser un lanceur d’installation .EXE extraire la bonne version et faire 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 le ensemble d'outils XML de Windows Installer (WiX) , mais Advanced Installer rend les choses si simples (et assez abordables) que je n’ai jamais vraiment cherché d’alternatives.

Une chose pour laquelle vous pouvez avoir encore besoin de WiX, même si vous utilisez Advanced Installer, concerne les actions personnalisées de votre classe d'installation .NET. Bien qu'il soit facile de spécifier certaines actions devant s'exécuter uniquement 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 de la structure 32 bits, même sur des ordinateurs 64 bits. .

Cela pourrait être résolu dans une version ultérieure, mais pour l'instant (ou si vous utilisez un autre outil pour créer vos MSI présentant 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 bitness approprié qui sera exécuté 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 augmenté un peu, même si son rapport qualité-prix est extrêmement bon comparé à InstallShield et ses semblables ...

Modifier: 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 construction, édition ou mise au point, et spécifie simplement l'architecture du processeur.

Autres conseils

Supposons que les DLL créées pour les deux plates-formes se trouvent à l'emplacement suivant:

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

Vous devez simplement éditer votre fichier .csproj à partir de ceci:

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

À ceci:

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

Vous devriez alors pouvoir construire votre projet en ciblant les deux plates-formes, et MSBuild recherchera dans le bon répertoire la plate-forme choisie.

Je ne suis pas sûr de la réponse totale à votre question - mais je pensais signaler un commentaire dans la section Informations supplémentaires de page de téléchargement de SQL Compact 3.5 SP1 voyant que vous regardez x64 - espérons que cela vous aidera.

  

En raison de modifications apportées à SQL Server Compact   SP1 et version 64 bits supplémentaire   support, installé centralement et mixte   environnements de mode de la version 32 bits de   SQL Server Compact 3.5 et 64 bits   version de SQL Server Compact 3.5 SP1   peut créer ce qui semble être   problèmes intermittents. Pour minimiser les   potentiels de conflits et pour permettre   déploiement neutre de la plate-forme de gestion   applications clientes, centralisées   installation de la version 64 bits de SQL   Server Compact 3.5 SP1 à l'aide du   Fichier Windows Installer (MSI) également   nécessite l'installation de la version 32 bits   de MSI SQL Server Compact 3.5 SP1   fichier. Pour les applications qui seulement   nécessite une version privée 64 bits, privée   déploiement de la version 64 bits de   SQL Server Compact 3.5 SP1 peut être   utilisé.

Je lis ceci comme " inclure les fichiers SQLCE 32 bits ainsi que les fichiers 64 bits " si distribution pour les clients 64bit.

Rend la vie intéressante, je suppose ... je dois dire que j'aime les & "; ce qui semble être des problèmes intermittents &"; la ligne ... sonne un peu comme & "vous imaginez des choses, mais juste au cas où, faites ceci ... &";

Concernant votre dernière question. Très probablement, vous ne pouvez pas résoudre ce problème dans un seul MSI. Si vous utilisez des dossiers de registre / système ou tout ce qui s'y rapporte, le MSI lui-même doit en être conscient et vous devez préparer un MSI 64 bits à installer correctement sur une machine 32 bits.

Il est possible que vous puissiez installer votre produit en tant qu’application 32-it tout en conservant son exécution en 64 bits, mais je pense que cela risque d’être un peu difficile à atteindre.

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

J'espère que ça aide. Voici un lien vers des informations relatives aux problèmes 32/64 bits: http: //blog.typemock. com / 2008/07 / registry-on-windows-64-bit-double-your.html

Si vous utilisez des actions personnalisées écrites en .NET dans le cadre de votre programme d'installation MSI, vous rencontrez un autre problème.

Le 'shim' qui exécute ces actions personnalisées est toujours en 32 bits, votre action personnalisée sera également exécutée en 32 bits, quelle que soit la cible spécifiée.

Plus d'infos & amp; certains ninja se déplacent pour se déplacer (essentiellement changer le MSI pour utiliser la version 64 bits de cette cale)

Construction d'un MSI dans Visual Studio 2005/2008 pour fonctionner sur un SharePoint 64

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

Vous pouvez générer deux solutions différemment et les fusionner ensuite! Je l'ai fait pour VS 2010. Et ça marche. J'ai eu 2 solutions différentes générées par CMake et je les ai fusionnées

Vous pouvez utiliser une condition sur un groupe d'éléments pour les références aux DLL du fichier de projet.
Ceci entraînera une nouvelle vérification de la condition et des références par Visual Studio chaque fois que vous modifierez la configuration active.
Ajoutez simplement une condition pour chaque configuration.

Exemple:

 <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>

Une version .Net avec des dépendances x86 / x64

Alors que toutes les autres réponses vous donnent une solution pour créer différentes versions en fonction de la plate-forme, je vous donne la possibilité de ne disposer que du & "AnyCPU &"; configuration et faire une construction qui fonctionne avec vos dlls x86 et x64.

Vous devez écrire du code de plomberie pour cela. Je ne pouvais pas que cela fonctionne avec app.config. Si quelqu'un d'autre connaît un moyen de le résoudre via app.config, j'aimerais vraiment savoir.

Résolution des dlls x86 / x64 correctes à l'exécution

Étapes:

  1. Utiliser AnyCPU dans csproj
  2. Décidez si vous ne faites que référencer les DLL x86 ou x64 dans vos csprojs. Adaptez les paramètres des tests unitaires aux paramètres d'architecture que vous avez choisis. Il est important de déboguer / exécuter les tests dans VisualStudio.
  3. Dans les propriétés de référence, définissez Copie locale & amp; Version spécifique à false
  4. Éliminez les avertissements d'architecture en ajoutant cette ligne au premier PropertyGroup de tous vos fichiers csproj où vous référencez x86 / x64: <ResolveAssemblyWarnOrErrorOnTargetArchitectureMismatch>None</ResolveAssemblyWarnOrErrorOnTargetArchitectureMismatch>
  5. Ajoutez ce script de post-construction à votre projet de démarrage, utilisez et modifiez les chemins de ce script afin de copier toutes vos dll x86 / x64 dans les sous-dossiers correspondants de votre build bin \ x86 \ bin \ x64 \

    xcopy /E /H /R /Y /I /D $(SolutionDir)\YourPathToX86Dlls $(TargetDir)\x86 xcopy /E /H /R /Y /I /D $(SolutionDir)\YourPathToX64Dlls $(TargetDir)\x64

    - > Lorsque vous démarrez une application maintenant, vous obtenez une exception que l'assemblage n'a pas pu être trouvé.

  6. Enregistrez l'événement AssemblyResolve dès le début du point d'entrée de votre application

    AppDomain.CurrentDomain.AssemblyResolve += TryResolveArchitectureDependency;
    

    avec cette méthode:

    /// <summary>
    /// Event Handler for AppDomain.CurrentDomain.AssemblyResolve
    /// </summary>
    /// <param name="sender">The app domain</param>
    /// <param name="resolveEventArgs">The resolve event args</param>
    /// <returns>The architecture dependent assembly</returns>
    public static Assembly TryResolveArchitectureDependency(object sender, ResolveEventArgs resolveEventArgs)
    {
        var dllName = resolveEventArgs.Name.Substring(0, resolveEventArgs.Name.IndexOf(","));
    
        var anyCpuAssemblyPath = $".\\{dllName}.dll";
    
        var architectureName = System.Environment.Is64BitProcess ? "x64" : "x86";
    
        var assemblyPath = $".\\{architectureName}\\{dllName}.dll";
    
        if (File.Exists(assemblyPath))
        {
            return Assembly.LoadFrom(assemblyPath);
        }
    
        return null;
    }
    
  7. Si vous avez des tests unitaires, créez une classe TestClass avec une méthode comportant un AssemblyInitializeAttribute et enregistrez-y le gestionnaire TryResolveArchitectureDependency-Handler ci-dessus. (Cela ne sera parfois pas exécuté si vous exécutez des tests uniques dans visual studio, les références ne seront pas résolues à partir du chutier UnitTest. Par conséquent, la décision prise à l'étape 2 est importante.)

Avantages:

  • Une installation / construction pour les deux plates-formes

Inconvénients:  - Aucune erreur lors de la compilation lorsque les DLL x86 / x64 ne correspondent pas.  - Vous devriez toujours lancer le test dans les deux modes!

Créez éventuellement un deuxième exécutable exclusif pour l'architecture x64 avec Corflags.exe dans le script post-construction

Autres variantes à essayer:  - Vous n'aurez pas besoin du gestionnaire d'événements AssemblyResolve si vous vous assurez que les dll sont copiées au début dans votre dossier binaire (Architecture du processus d'évaluation - & Gt; déplacez les dll correspondantes de x64 / x86 vers le dossier bin et vice-versa.)  - Dans Installer, évaluez l’architecture, supprimez les binaires de la mauvaise architecture et déplacez les bons dans le dossier bin.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top