37 votes

L'application ne fonctionne pas avec les DLL VS 2008 SP1, la version précédente fonctionne avec les versions RTM

Depuis le passage à partir de Visual Studio 6 pour Visual Studio 2008, nous avons été à l'aide de la MFC90.dll et msvc[pr]90.dll avec les fichiers manifest dans un privé côté-à-côte, de configuration, de manière à ne pas vous soucier de versions ou de les installer dans le système.

Pré-SP1, ce qui fonctionnait bien (et fonctionne toujours très bien sur nos ordinateurs de développement). Maintenant que nous avons fait quelques tests post-SP1, j'ai été en tirant sur mes cheveux depuis hier matin.

Tout d'abord, notre installateur NSIS script tire les dll et les fichiers manifeste à partir du dossier redist. Ce n'est plus correct, que l'application encore des liens vers la version RTM.

J'ai donc ajouté le définir pour _BIND_TO_CURRENT_VCLIBS_VERSION=1 pour l'ensemble de nos projets, de sorte que ils vont utiliser le SP1 Dll dans le dossier redist (ou ultérieure en tant que nouveau service packs de sortir). Il m'a fallu des heures pour trouver ce.

J'ai une double vérification de l'généré les fichiers manifeste dans les fichiers intermédiaires dossier à partir de la compilation, et ils correctement les 9.0.30729.1 versions SP1. J'ai le double et le triple vérifié dépend d'une machine de nettoyage: tous les liens vers les locaux dll sans erreurs.

L'exécution de l'application obtient toujours le message d'erreur suivant:

L'application n'a pas réussi à s'initialiser correctement (0xc0150002). Cliquez sur OK pour fermer l'application.

Aucun des recherches que j'ai faites sur google ou microsoft sont venus avec tout ce qui se rapporte à mes questions spécifiques (mais il y a des hits de retour à 2005 avec ce message d'erreur).

Tout avait le même problème avec le SP1?

Options:

  • Trouver le problème et de le résoudre de sorte qu'il fonctionne comme il se doit (de préférence)
  • Installer le redist
  • déterrer les vieux RTM les dll et les fichiers manifeste et enlever le #define utiliser les modèles actuels. (Je l'ai eu dans une version antérieure du programme d'installation de construire, car Microsoft explosions de votre dossier redist!)

Edit: j'ai essayé de re-construction avec les définir éteint (lien vers la version RTM dll), et qui fonctionne aussi longtemps que la RTM dll sont installés dans le dossier. Si le SP1 de dll sont supprimés, il obtient l'erreur suivante:

c:\Program Files\...\...\X.exe

Cette application n'a pas pu démarrer car la configuration de l'application est incorrecte. La réinstallation de cette application peut corriger ce problème.

A personne d'autre n'avait à traiter de cette question?

Edit: Juste pour sourire, j'ai téléchargé et exécuté le vcredist_x86.exe pour VS2008SP1 sur ma machine de test. Elle fonctionne. Avec le SP1 Dll. Et mon RTM lié app. Mais PAS dans un privé côté-à-côte de distribution qui a travaillé pré-SP1.

40voto

Roel Points 9657

J'ai lutté contre ce problème moi-même la semaine dernière et me considère un peu d'un expert maintenant ;)

Je suis sûr à 99% que toutes les dll et les bibliothèques statiques ont été recompilé avec la version SP1. Vous avez besoin de mettre

#define _BIND_TO_CURRENT_MFC_VERSION 1
#define _BIND_TO_CURRENT_CRT_VERSION 1

dans chaque projet que vous êtes en utilisant. Pour chaque projet, d'une taille dans le monde réel, il est très facile d'oublier certains petits lib qui n'a pas été recompilé.

Il y a plus de drapeaux que de définir quelles sont les versions de bind; elle est documentée sur http://msdn.microsoft.com/en-us/library/cc664727%28v=vs.90%29.aspx . Comme une alternative pour les lignes ci-dessus, vous pouvez aussi mettre

#define _BIND_TO_CURRENT_VCLIBS_VERSION 1

qui va se lier à la version la plus récente de tous les VC libs (CRT, MFC, ATL, OpenMP).

Ensuite, vérifiez ce que la embarqués manifeste dit. Télécharger XM Éditeur de Ressources: http://www.wilsonc.demon.co.uk/d10resourceeditor.htm. Ouvert tous les dll et exe dans votre solution. Regardez sous "XP Thème Manifeste'. Vérifiez que la "version" de l'attribut sur le côté droit est "9.0.30729.1'. Si c'est "9.0.21022", certaines statique de la bibliothèque est en tirant dans le manifeste pour l'ancienne version.

Ce que j'ai trouvé est que, dans de nombreux cas, les deux versions ont été inclus dans le manifeste. Cela signifie que certaines bibliothèques utilisent la version sp1, et d'autres pas.

Une excellente façon de déboguer des bibliothèques n'ont pas les directives de préprocesseur ensemble: modifier temporairement votre plate-forme en-têtes, de sorte que la compilation s'arrête lorsqu'il tente d'intégrer la vieille manifeste. Ouvert C:\Program Files\Microsoft Visual Studio 9.0\VC\crt\include\crtassem.h. De recherche pour le "21022' chaîne. De définir, de mettre quelque chose d'incorrect (changement de "définir" pour "blehbleh' ou). De cette façon, lorsque vous compilez un projet où l' _BIND_TO_CURRENT_CRT_VERSION préprocesseur option n'est pas activée, votre compilation s'arrête et vous saurez que vous avez besoin d'en ajouter, ou fait en sorte qu'il est appliqué partout.

Assurez-vous également d'utiliser Dependency Walker, de sorte que vous savez ce que les dll sont tirés dans. Il est plus facile d'installer un nouveau Windows version XP sans les mises à jour (uniquement SP2) sur un ordinateur virtuel. De cette façon, vous savez qu'il n'y a rien dans le dossier côte à côte qui est utilisé à la place de la côté-à-côte dll que vous avez fournies.

14voto

Dimitri C. Points 6455

Pour comprendre le problème, je pense qu'il est important de réaliser qu'il y a quatre numéros de version impliqués:

  • (A) La version de la CR fichiers d'en-tête de qui la .exe est compilé.
  • (B) La version du fichier manifest qui est incorporé dans la section des ressources de cet .exe. Par défaut, ce fichier est généré automatiquement par Visual Studio.
  • (C) La version de la CR .Dll (une partie de la côte-à-côté d'assemblage) vous copie dans le même répertoire que le .exe.
  • (D) La version de la CR fichiers manifest (une partie de la côte-à-côté d'assemblage) vous copie dans le même répertoire que le .exe.

Il existe deux versions de la VC 2008 DLL est en cours d'exécution:

  • v1: 9.0.21022.8
  • v2: 9.0.30729.4148

Pour plus de clarté, je vais utiliser la v1/v2 notation. Le tableau suivant montre un certain nombre de situations possibles:

Situation | .exe (A) | embedded manifest (B) | VC DLLs (C) | VC manifests (D)
-----------------------------------------------------------------------------
1         | v2       | v1                    | v1          | v1         
2         | v2       | v1                    | v2          | v2          
3         | v2       | v1                    | v2          | v1
4         | v2       | v2                    | v2          | v2

Les résultats de ces situations lors de l'exécution de l' .exe sur une surface propre, Vista SP1 installation sont:

  • Situation 1: un message est affiché, en disant: "Le point d'entrée de procédure XYZXYZ n'a pas pu être localisé dans la bibliothèque de liens dynamiques".

  • Situation 2: rien ne semble se produire lors de l'exécution de l' .exe, mais l'événement suivant est enregistré dans Windows' "Observateur d'Événements / journal d'Application":

    Création du contexte d'Activation a échoué pour "C:\Path\file.exe".Erreur manifeste ou de stratégie de fichier "C:\Path\Microsoft.VC90.CRT.MANIFEST" sur la ligne 4. Composante de l'identité trouvée dans le manifeste ne correspond pas à l'identité de l'élément demandé. De référence est Microsoft.VC90.CRT,processorArchitecture="x86",publicKeyToken="1fc8b3b9a1e18e3b",type="win32",version="9.0.21022.8". La définition est Microsoft

  • Situation 3: tout semble bien fonctionner. C'est remicles2 de la solution.

  • Situation 4: c'est comment il devrait être fait. Malheureusement, comme Roel l'indique, il peut être assez difficile à mettre en œuvre.

Maintenant, ma situation (et je pense que c'est le même que crashmstr s) est n ° 1. Le problème est que Visual Studio, pour une raison ou une autre génération de code client (A) pour la v2, mais pour une raison ou une autre, génère un v1 fichier manifest (B). Je n'ai aucune idée de l'endroit où la version (A) peut être configuré.

Notez que toute cette explication est encore dans le contexte de privé assemblées.

Mise à jour: finalement je commence à comprendre ce qui se passe. Apparemment, Visual Studio génère du code client (A) pour la v2 par défaut, contrairement à ce que j'ai lu sur certains Microsoft blogs. Le _BIND_TO_CURRENT_VCLIBS_VERSION drapeau ne sélectionne la version dans le générés fichier manifest (B), mais cette version sera ignorée lors de l'exécution de l'application.

Conclusion

Un .exe qui est compilé par Visual Studio 2008 des liens vers les versions les plus récentes de la VC90 Dll par défaut. Vous pouvez utiliser le _BIND_TO_CURRENT_VCLIBS_VERSION drapeau pour contrôler la version de la VC90 bibliothèques sera généré dans le fichier de manifeste. Cela évite en effet de la situation 2, où vous obtenez le message d'erreur "manifeste ne correspond pas à l'identité de la composante de la demande". Il explique aussi pourquoi la situation 3, fonctionne très bien, que même sans le _BIND_TO_CURRENT_VCLIBS_VERSION drapeau de la demande est liée à des versions plus récentes de la VC Dll.

La situation est encore plus étrange avec le public side-by-side assemblées, où vcredist a terme, la VC 9.0 Dll dans Windows SxS répertoire. Même si l' .exe le fichier de manifeste d'états que les versions anciennes de la Dll doit être utilisé (c'est le cas lorsque le _BIND_TO_CURRENT_VCLIBS_VERSION indicateur n'est pas défini), Windows ignore ce numéro de version par défaut! Au lieu de cela, Windows va utiliser une version plus récente si elle est présente sur le système, sauf quand un "fichier de configuration d'application" est utilisé.

Suis-je le seul qui pense que ceci est source de confusion?

Donc, en résumé:

  • Pour le privé, assemblées, utilisez le _BIND_TO_CURRENT_VCLIBS_VERSION drapeau dans le .exe du projet et tous dépendants .lib projets.
  • Pour les assemblées publiques, ce n'est pas nécessaire, que Windows va automatiquement sélectionner la bonne version de l' .Dll à partir de la SxS répertoire.

4voto

Roel Points 9657

Je viens de me rappeler une autre astuce que j'ai utilisé pour savoir qui bibliothèques statiques ont été mauvais comportement: 'grep' à travers les bibliothèques statiques pour la chaîne "21022'. CEPENDANT, n'utilisez pas "normal", des outils comme grep wingrep parce qu'ils ne vous montrent pas ces chaînes (ils pensent que c'est un fichier binaire et de regarder pour la première, chaîne non-unicode). Utiliser les "cordes" de l'utilitaire du kit de ressources (aujourd'hui dans le Russinovich site, je pense). Que l'on va grep par le biais de fichiers binaires ok. Vous laissez donc cette 'strings' aller à travers l'ensemble de votre arborescence des sources et vous verrez les fichiers binaires (les dll et les bibliothèques statiques) qui contiennent des références à la mauvaise manifeste (ou à l'manifeste avec la mauvaise version en elle).

4voto

remicles2 Points 131

Un autre outil intéressant pour afficher les manifestes exe et dll est Manifest View , qui ne pourra pas être exécuté correctement si XP est correctement installé, car il dépend de la version 9.0.21022.

2voto

remicles2 Points 131

Pour votre troisième option, vous pouvez probablement trouver les Dll et manifeste pour la 9.0.21022 version dans le C:\WINDOWS\WinSxS répertoire sur votre machine de dev. Si vous le pouvez, alors vous pouvez configurer votre propre répertoire redist et d'installation de ces fichiers dans votre application.

Alternativement, vous pouvez utiliser le 9.0.30729.1 ceux fournis avec Visual Studio et forge le manifeste que vous installez avec votre application de signaler qu'il fournit le 9.0.21022 Dll, et pas 9.0.30729.1. Le moteur d'exécution de l'éditeur de liens ne semblent pas à l'esprit. Voir ce blog, qui a été extrêmement utile pour la résolution de ces problèmes, pour plus d'informations.

Les deux solutions de contournement fixe les problèmes que j'avais avec le déploiement de la Dll en tant que privé, assemblées avec VS2008 Express.

Roel la réponse est la voie à suivre pour votre première option ("fix it right"), mais si vous dépendez d'une bibliothèque qui dépend 9.0.21022 (et votre manifeste donc des listes deux versions), puis la troisième option peut être la seule voie à suivre si vous ne voulez pas manquer vcredist_x86.exe.

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