Question

Depuis 2006, je vois qu’il n’est pas possible de créer une dll contre Microsoft et de les déployer ensemble ( http://www.ddj.com/windows/184406482 ). Je suis profondément dérouté par manifest, SxS et autres: la documentation MSDN est vraiment médiocre, avec des références circulaires; spécialement parce que je suis plus un gars sous Unix, je trouve tous ces informateurs. Mon problème principal est de lier une dll à msvc9 ou msvc8: puisque ces runtime ne sont pas redistribuables, quelles sont les étapes pour lier et déployer une telle dll? En particulier, comment le manifeste est-il généré (je ne veux pas mt.exe, je veux quelque chose qui soit portable entre les compilateurs), comment sont-ils incorporés, utilisés? Que signifie assembler côte à côte?

En gros, où puis-je trouver n'importe quel type de spécification au lieu du jargon MS?

Merci à toutes les personnes qui ont répondu, cela a été vraiment utile,

Était-ce utile?

La solution

Nous utilisons un simple fichier include dans toutes nos applications & amp; DLL's, vcmanifest.h, puis définissez tous les projets pour incorporer le fichier manifeste.

vcmanifest.h

/*----------------------------------------------------------------------------*/

#if _MSC_VER >= 1400

/*----------------------------------------------------------------------------*/

#pragma message ( "Setting up manifest..." )

/*----------------------------------------------------------------------------*/

#ifndef _CRT_ASSEMBLY_VERSION
#include <crtassem.h>
#endif 

/*----------------------------------------------------------------------------*/

#ifdef WIN64
    #pragma message ( "processorArchitecture=amd64" )
    #define MF_PROCESSORARCHITECTURE "amd64"
#else
    #pragma message ( "processorArchitecture=x86" )
    #define MF_PROCESSORARCHITECTURE "x86"
#endif 

/*----------------------------------------------------------------------------*/

#pragma message ( "Microsoft.Windows.Common-Controls=6.0.0.0") 
#pragma comment ( linker,"/manifestdependency:\"type='win32' " \
                  "name='Microsoft.Windows.Common-Controls' " \
                  "version='6.0.0.0' " \
                  "processorArchitecture='" MF_PROCESSORARCHITECTURE "' " \
                  "publicKeyToken='6595b64144ccf1df'\"" )

/*----------------------------------------------------------------------------*/

#ifdef _DEBUG
    #pragma message ( __LIBRARIES_ASSEMBLY_NAME_PREFIX ".DebugCRT=" _CRT_ASSEMBLY_VERSION ) 
    #pragma comment(linker,"/manifestdependency:\"type='win32' "            \
            "name='" __LIBRARIES_ASSEMBLY_NAME_PREFIX ".DebugCRT' "         \
            "version='" _CRT_ASSEMBLY_VERSION "' "                          \
            "processorArchitecture='" MF_PROCESSORARCHITECTURE "' "         \
            "publicKeyToken='" _VC_ASSEMBLY_PUBLICKEYTOKEN "'\"")
#else
    #pragma message ( __LIBRARIES_ASSEMBLY_NAME_PREFIX ".CRT=" _CRT_ASSEMBLY_VERSION ) 
    #pragma comment(linker,"/manifestdependency:\"type='win32' "            \
            "name='" __LIBRARIES_ASSEMBLY_NAME_PREFIX ".CRT' "              \
            "version='" _CRT_ASSEMBLY_VERSION "' "                          \
            "processorArchitecture='" MF_PROCESSORARCHITECTURE "' "         \
            "publicKeyToken='" _VC_ASSEMBLY_PUBLICKEYTOKEN "'\"")
#endif

/*----------------------------------------------------------------------------*/

#ifdef _MFC_ASSEMBLY_VERSION
    #ifdef _DEBUG
        #pragma message ( __LIBRARIES_ASSEMBLY_NAME_PREFIX ".MFC=" _CRT_ASSEMBLY_VERSION ) 
        #pragma comment(linker,"/manifestdependency:\"type='win32' "            \
                "name='" __LIBRARIES_ASSEMBLY_NAME_PREFIX ".MFC' "              \
                "version='" _MFC_ASSEMBLY_VERSION "' "                          \
                "processorArchitecture='" MF_PROCESSORARCHITECTURE "' "         \
                "publicKeyToken='" _VC_ASSEMBLY_PUBLICKEYTOKEN "'\"")
    #else
        #pragma message ( __LIBRARIES_ASSEMBLY_NAME_PREFIX ".MFC=" _CRT_ASSEMBLY_VERSION ) 
        #pragma comment(linker,"/manifestdependency:\"type='win32' "            \
                "name='" __LIBRARIES_ASSEMBLY_NAME_PREFIX ".MFC' "              \
                "version='" _MFC_ASSEMBLY_VERSION "' "                          \
                "processorArchitecture='" MF_PROCESSORARCHITECTURE "' "         \
                "publicKeyToken='" _VC_ASSEMBLY_PUBLICKEYTOKEN "'\"")
    #endif
#endif /* _MFC_ASSEMBLY_VERSION */

/*----------------------------------------------------------------------------*/

#endif /* _MSC_VER */

/*----------------------------------------------------------------------------*/

Autres conseils

La chose la plus simple à faire: En supposant une installation par défaut de VS2005, vous aurez un chemin tel que:

C:\Program Files\Microsoft Visual Studio 8\VC\redist\x86\Microsoft.VC80.CRT

Allez chercher les fichiers dans ce dossier de redistribution et placez le .manifest ET le msvcr80.dll (au moins) dans le dossier de vos applications .exe. Ces fichiers, présents à la racine de votre installation, devraient permettre à votre fichier exe et à toutes les dll qui y sont liées de fonctionner parfaitement sans recourir à la fusion de modules, de fichiers MSI ou de tout type de détection "juste à temps" indiquant que le moteur d'exécution n'est pas installé.

Voici l'entrée de blog expliquant le raisonnement derrière le SxS décision de crt pour VC ++ . Cela inclut d’expliquer à quel point il est mauvais de lier statiquement le client et pourquoi vous ne devriez pas le faire.

Voici la documentation sur la liaison statique de la crt .

Eh bien, j'ai rencontré certains de ces problèmes, alors peut-être que certains de mes commentaires seront utiles.

  1. Le manifeste est un fichier XML. Alors que VS peut en créer un pour vous lors de la compilation, l’autre solution consiste à produire un fichier de ressources (.rc) et à le compiler dans un fichier de ressources compilé (.res) à l’aide du compilateur de ressources (rc.exe) inclus dans VS . Vous voudrez exécuter la ligne de commande VS à partir du menu Outils, ce qui permettra à rc de se trouver dans le chemin, ainsi que de définir différentes variables d'environnement correctement. Puis compilez votre ressource. Le fichier .res résultant peut être utilisé par d’autres compilateurs.
  2. Assurez-vous que la taille de votre fichier XML manifeste est divisible par 4. Ajoutez un espace au milieu de celui-ci pour y parvenir, si nécessaire. Essayez d’éviter d’avoir des caractères avant la balise XML d’ouverture ou après la balise XML de fermeture. J'ai parfois eu des problèmes avec cela. Si vous effectuez l'étape 2 de manière incorrecte, attendez-vous à des erreurs de configuration côte à côte. Vous pouvez vérifier si c'est votre erreur en ouvrant le fichier exe dans un éditeur de ressources (par exemple, devenv.exe) et en examinant la ressource manifeste. Vous pouvez également voir un exemple de manifeste correct en ouvrant simplement un fichier construit. Notez que les dll et les exes ont de très petites différences quant à l'identifiant de la ressource à attribuer.

Vous voudrez probablement tester sur Vista pour vous assurer qu'il fonctionne correctement.

Ils sont redistribuables et vous avez des packages redistribuables dans le répertoire msvs.

Construisez avec le temps d’exécution de votre choix, ajoutez le paquet correspondant à votre installateur et ne vous embêtez pas - cela fonctionnera. La différence est qu’ils sont installés dans un endroit différent maintenant (mais c’est également là que votre application va chercher des bibliothèques).

Sinon, MSDN ou tout autre livre pas trop ancien sur la programmation Windows c ++.

Merci pour la réponse. Pour le déploiement en tant que tel, je peux voir 3 options, puis:

  • Utilisation de la directive de fusion .msi.
  • Utiliser le package VS redistribuable et l'exécuter avant mon propre installateur
  • Copie des fichiers redistribuables dans ma propre application. Mais dans ce cas, comment puis-je y faire référence dans une hiérarchie de système de fichiers (par exemple, bar / foo1 / foo1.dll et bar / foo2 / foo2.dll font référence à msvcr90.dll dans bar /)? Je veux dire en plus de ce qui est évident et moche "copiez la dll dans chaque répertoire où vous avez dll, ce qui en dépend).

Vous ne pouvez pas utiliser CRT VC ++ 8 SP1 / 9 en tant que module de fusion sous Vista et Windows Server 2008 si vous souhaitez démarrer des services ou exécuter des programmes que vous ne souhaitez pas exécuter avant l'installation de " InstallFinalize " action dans le MSI.

Cela est dû au fait que les dll sont installées dans WinSXS dans le répertoire "InstallFinalize". action.

Mais le MSI " ServiceStart " l'action vient avant cela.

Vous devez donc utiliser soit un http://www.davidguyer.us/bmg/ publier.htm "

Ou cherchez à utiliser le programme d'installation en utilisant le programme d'installation 4.5. Mais cela signifie que vous avez besoin d’un programme d’amorçage pour installer la version 4.5, ce qui semble un peu inutile.

Si vous envisagez de déployer les fichiers Microsoft DLL / .manifest et utilisez JNI Java, vous devrez les placer dans le répertoire bin de votre JDK / JRE.

Si vous exécutez l'application dans JBoss, vous devrez les placer dans le répertoire JBoss / bin.

Vous pouvez placer votre DLL JNI le cas échéant pour votre application.

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