App läuft nicht mit VS 2008 SP1-DLLs frühere version funktioniert mit der RTM-Versionen

StackOverflow https://stackoverflow.com/questions/59635

  •  09-06-2019
  •  | 
  •  

Frage

Da unser Schalter von Visual Studio 6, Visual Studio 2008, wir haben mit der MFC90.dll und msvc[pr]90.dlls zusammen mit der manifest-Dateien in einem eigenen side-by-side-Konfiguration, so nicht sorgen über die Version oder installieren Sie das system.

Pre-SP1, das war wunderbar funktioniert (und funktioniert immer noch gut auf unsere Entwickler-Maschinen).Nun, wir haben einige Tests post-SP1 ich habe mein Haar ziehen seit gestern morgen.

First off, unser NSIS installer-Skript zieht die dlls und manifest-Dateien aus dem Ordner "redist".Diese wurden nicht mehr korrekt, da die app immer noch links auf die RTM-version.

Also fügte ich die definieren für _BIND_TO_CURRENT_VCLIBS_VERSION=1 für alle unsere Projekte so, dass Sie das SP1-DLLs in den Ordner redist (oder nachfolgenden als neuen service packs kommen).Es hat mich zu dieser Stunde zu finden.

Ich habe doppelt überprüft das generierte manifest-Dateien in das temporäre Dateien Ordner aus der Zusammenstellung, und Sie korrekt Liste der 9.0.30729.1 SP1-Versionen.Ich habe doppelt und dreifach geprüft, hängt von einem sauberen Maschine:es werden alle Verknüpfungen zu den lokalen dlls mit keine Fehler.

Die app ausführt, wird immer noch der folgende Fehler angezeigt:

Die Anwendung konnte nicht richtig initialisiert werden (0xc0150002).Klicken Sie auf OK um die Anwendung zu beenden.

Keine der Suche habe ich auf google oder microsoft haben mit etwas kommen, das bezieht sich auf meine spezifischen Fragen (es gibt aber schlägt zurück, um 2005 mit dieser Fehlermeldung).

Jeder hatte ähnliche problem mit SP1?

Optionen:

  • Finden Sie das problem und korrigieren Sie es, damit es funktioniert wie es sollte (bevorzugt)
  • Installieren Sie die redist
  • Graben Sie die alten RTM-dlls und manifest-Dateien und entfernen Sie die #define zu verwenden, die aktuelle.(Ich habe Sie in einem früheren installer bauen, da Microsoft Blasten aus dem redist-Ordner!)

Edit: Ich habe versucht, re-Gebäude mit dem definieren ausgeschaltet (link zu RTM dlls), und das funktioniert solange, wie der RTM-dlls installiert sind, in den Ordner.Wenn Sie das SP1-dlls gelöscht, es wird die folgende Fehlermeldung angezeigt:

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

Diese Anwendung konnte nicht gestartet werden, da die Anwendungskonfiguration falsch ist.Eine Neuinstallation der Anwendung könnte dieses problem beheben.

Hat sonst niemand hatte, mit diesem Problem umzugehen?

Edit: Nur für grins, ich heruntergeladen und ran an die vcredist_x86.exe für VS2008SP1 auf meinem test-Maschine. Es funktioniert.Mit der SP1-DLLs.Und meine RTM-app verknüpft.Aber NICHT in einem eigenen side-by-side-distribution gearbeitet pre-SP1.

War es hilfreich?

Lösung

Ich habe gekämpft, dieses problem selbst Letzte Woche und halte mich auch etwas von einem Experten jetzt ;)

Ich bin mir zu 99% sicher sein, dass nicht alle dlls und statischen Bibliotheken kompiliert, die mit der SP1-version.Sie müssen

#define _BIND_TO_CURRENT_MFC_VERSION 1
#define _BIND_TO_CURRENT_CRT_VERSION 1

in jeder Projekt, das Sie gerade verwenden.Für jedes Projekt wird einer realen Größe, es ist sehr leicht zu vergessen, einige kleine lib, war nicht neu kompiliert.

Es gibt mehrere flags, die definieren, welche Versionen zu binden;es ist dokumentiert auf http://msdn.microsoft.com/en-us/library/cc664727%28v=vs.90%29.aspx .Als alternative zu den Linien, die oben, Sie können auch setzen

#define _BIND_TO_CURRENT_VCLIBS_VERSION 1

die Bindung an die neueste version aller VC-libs (CRT, MFC, ATL, OpenMP).

Überprüfen Sie danach, was die eingebettete manifest sagt.Download-XM-Ressourcen-Editor: http://www.wilsonc.demon.co.uk/d10resourceeditor.htm.Öffnen Sie alle dll-und exe-Datei in Ihrer Lösung.Schauen Sie unter 'XP-Theme Manifest".Überprüfen Sie, dass die "version" - Attribut auf der rechten Seite ist "9.0.30729.1'.Wenn es '9.0.21022", einige statische Bibliothek zieht in das manifest für die alte version.

Was ich fand, ist, dass in vielen Fällen, beide - Versionen enthalten waren, die im manifest.Dies bedeutet, dass einige Bibliotheken verwenden Sie die sp1-version und andere nicht.

Ein guter Weg, um die debug-Bibliotheken, die nicht über die Präprozessor-Direktiven legen:vorübergehend ändern Sie Ihre Plattform-Headern, so dass die Kompilierung bricht, wenn er versucht zum einbetten der alten manifestieren.Öffnen C:\Program Files\Microsoft Visual Studio 9.0\VC\crt\include\crtassem.h.Suche nach dem "21022" string.In diesem definieren, setzen Sie etwas ungültig (ändern 'definieren' auf 'blehbleh' oder so).Auf diese Weise, wenn Sie kompilieren ein Projekt, bei dem die _BIND_TO_CURRENT_CRT_VERSION Präprozessor-flag ist nicht gesetzt, Ihre Zusammenstellung wird stoppen und Sie werden wissen, dass Sie brauchen, um Sie hinzuzufügen oder aus sicher, dass es überall angewendet.

Auch stellen Sie sicher, Dependency Walker, so dass Sie wissen, was dlls gezogen, in.Es ist am einfachsten zu installieren, eine Neuinstallation von Windows XP-Kopie keine updates (nur SP2) auf einer virtuellen Maschine.Auf diese Weise wissen Sie sicher, dass es nichts in der SxS-Ordner, der verwendet wird, anstatt die side-by-side dlls, die Sie angegeben haben.

Andere Tipps

Um das problem zu verstehen, ich denke, es ist wichtig zu erkennen, dass es vier Versionsnummern beteiligt:

  • (A) Die version des VC-header-Dateien, auf die das .exe-Datei kompiliert wird.
  • (B) Die version von die manifest-Datei, die eingebettet ist in die Ressourcen, die Abschnitt, die .exe.Standardmäßig ist diese manifest-Datei wird automatisch von Visual Studio.
  • (C) Die version des VC .DLLs (der Teil der Seite-an-Seite-Montage) kopieren Sie in das gleiche Verzeichnis wie die .exe.
  • (D) Die version des VC-manifest-Dateien (Teil des Seite-an-Seite-Montage) kopieren Sie in das gleiche Verzeichnis wie die .exe.

Es gibt zwei Versionen des VC 2008 DLL ' s in der Ausführung:

  • v1:9.0.21022.8
  • v2:9.0.30729.4148

Aus Gründen der übersichtlichkeit verwende ich die v1/v2-notation.Die folgende Tabelle zeigt eine Reihe von möglichen Situationen:

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

Die Ergebnisse dieser Situationen, die bei der Ausführung der .exe-Datei auf eine saubere Vista SP1 installation sind:

  • Situation 1:ein popup wird angezeigt, die besagt:"Die Prozedur Eintrag Punkt XYZXYZ nicht gefunden werden konnte in der dynamic link library".

  • Situation 2:nichts scheint zu passieren, wenn läuft das .exe-Datei, aber das folgende Ereignis wird protokolliert, der Windows "Ereignisanzeige / Anwendungs-log":

    Activation context generation failed for "C:\Path\file.exe".Fehler in manifest-oder Richtliniendatei "C:\Path\Microsoft.VC90.CRT.MANIFEST" auf der Linie 4.Komponente Identität gefunden im manifest stimmt nicht mit der Identität der Komponente angefordert.Referenz Microsoft.VC90.CRT,processorArchitecture="x86",publicKeyToken="1fc8b3b9a1e18e3b",type="win32",version="9.0.21022.8".Definition Microsoft

  • Situation 3:alles scheint gut zu funktionieren.Dies ist remicles2 Lösung.

  • Situation 4:dies ist wie es getan werden sollte.Leider, wie Roel zeigt, ist es eher schwer zu realisieren.

Nun, meine situation (und ich denke, es ist das gleiche wie crashmstr s) ist die nr 1.Das problem ist, dass Visual Studio, die für einen oder anderen Grund generiert der client-code (A) für die v2, aber für einen oder anderen Grund, erzeugt eine v1-manifest-Datei (B).Ich habe keine Ahnung, wo Sie-version (Ein) konfiguriert werden können.

Hinweis diese ganze Erklärung ist noch im Rahmen private Assemblys.

Update:endlich beginne ich zu verstehen, was Los ist.Offenbar, Visual Studio generiert der client-code (A) für v2 by default, im Gegensatz zu dem, was ich gelesen habe, auf einige Microsoft-blogs.Die _BIND_TO_CURRENT_VCLIBS_VERSION fahne, nur wählt die version in der generierten Manifestdatei (B), aber diese version wird ignoriert, wenn die Anwendung ausgeführt wird.

Fazit

Ein .exe-Datei, die kompiliert mit Visual Studio 2008 links zu den neusten Versionen der VC90-DLLs durch Standard.Sie können verwenden Sie die _BIND_TO_CURRENT_VCLIBS_VERSION Flagge um zu kontrollieren, welche version des VC90-Bibliotheken generiert, der das manifest-Datei.Dies vermeidet die situation, 2, wo Sie die Fehlermeldung erhalten, dass "manifest stimmt nicht mit der Identität der Komponente angefordert".Es erklärt auch, warum die situation 3 funktioniert, als auch ohne die _BIND_TO_CURRENT_VCLIBS_VERSION Flagge die Anwendung wird mit den neuesten Versionen der VC-DLLs.

Die situation wird noch merkwürdiger, die mit öffentlichen side-by-side assemblies, wo vcredist ausgeführt wurde, indem das VC 9.0 DLLs in der Windows-SxS-Verzeichnis.Auch wenn die .exe ist die manifest-Datei besagt, dass die alten Versionen der DLLs genutzt werden sollen (dies ist der Fall, wenn die _BIND_TO_CURRENT_VCLIBS_VERSION flag ist nicht gesetzt), Windows ignoriert diese version number by default!Stattdessen, wird von Windows eine neuere version, wenn auf dem system vorhanden, außer wenn ein "application configuration file" verwendet wird.

Bin ich der einzige, der denkt, das ist verwirrend?

So Zusammenfassung:

  • Für private Assemblys, verwenden Sie das _BIND_TO_CURRENT_VCLIBS_VERSION-flag in der .exe-Projekt-und alle abhängig .lib Projekte.
  • Für öffentliche Versammlungen, dies ist jedoch nicht erforderlich, da Windows wird automatisch wählen Sie die richtige version des .DLLs aus der SxS-Verzeichnis.

Ich erinnerte mich nur ein weiterer trick, den ich verwendet zu finden heraus, welche statischen Bibliotheken waren schlecht verhält:'grep' durch die statischen Bibliotheken für die Zeichenfolge "21022'.JEDOCH, nicht mit den 'normalen' grep-tools wie wingrep, weil Sie nicht zeigen, dass Sie diese strings (Sie denken, es ist eine binäre Datei und suchen nach der rohen, nicht-unicode-Zeichenfolge).Verwenden Sie den "strings" - Dienstprogramm von der Ressourcen-kit (jetzt in der Russinovich Seite, die ich denke).Dass man grep durch binaries ok.Also lass dir diese "strings" gehen Sie durch Ihre gesamten Quellcode und sehen Sie die Binärdateien (dlls und statische Bibliotheken) enthalten Verweise auf die falsche manifest (oder das manifest mit die falsche version drin).

Ein weiteres schönes tool zum anzeigen von exe-und dll manifestiert, ist Manifest-Ansicht, die passenderweise genug, nicht laufen, auf eine saubere Installation von XP, da es hängt davon ab 9.0.21022.

Für Ihre Dritte option ist, können Sie wahrscheinlich finden Sie die DLLs und manifeste für die 9.0.21022-version in der C:\WINDOWS\WinSxS Verzeichnis auf Ihrem dev-Maschine.Wenn Sie können, dann können Sie setup Ihre eigenen redist-Verzeichnis und installieren Sie diese Dateien mit Ihrer app.

Alternativ können Sie über die 9.0.30729.1 diejenigen geliefert, die mit Visual Studio-und zwar das manifest der Installation Ihrer app zu berichten, dass es versorgt die 9.0.21022-DLLs und nicht 9.0.30729.1.Der Laufzeit-linker nicht zu stören scheint.Diese finden Sie unter blog, wurde , die immens hilfreich für die Lösung dieser Probleme, für mehr Informationen.

Beide Problemumgehungen behoben, die Probleme hatte ich mit der Bereitstellung von DLLs als private Assemblys mit VS2008 Express.

Roel s Antwort ist der Weg zu gehen für Ihre erste option ("fix it-Recht"), aber wenn Sie sind abhängig von einer Bibliothek abhängt 9.0.21022 (und Ihr manifest listet somit beide Versionen), dann die Dritte option könnte sein, die nur Weg zu gehen, wenn Sie nicht wollen, dass es vcredist_x86.exe.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top