Problembehandlung bei isolierten Anwendungen und parallelen Assemblys (C/C++)

Das Laden einer C/C++-Anwendung kann fehlschlagen, wenn abhängige Visual C++-Bibliotheken nicht gefunden werden. Eine Liste potenzieller Laufzeitfehler finden Sie unter Verteilen von Visual C++-Dateien. In diesem Abschnitt werden die häufigsten Ursachen für Fehler beim Laden einer C/C++-Anwendung beschrieben und Schritte zur Lösung des jeweiligen Problems vorgeschlagen.

Wenn eine Anwendung, die auf einem Computer bereitgestellt wird, auf dem Visual C++ nicht installiert ist, abstürzt und dabei eine Fehlermeldung angezeigt wird, die ähnlich lautet wie die unter Verteilen von Visual C++-Dateien aufgeführten Fehlermeldungen, müssen zur Feststellung der Fehlerursache mehrere Dinge überprüft werden.

  1. Führen Sie die Schritte in Abhängigkeiten einer Visual C++-Anwendung aus. Der Dependency Walker zeigt den größten Teil der Abhängigkeiten für eine bestimmte Anwendung oder DLL an. Wenn Sie feststellen, dass einige DLLs fehlen, installieren Sie diese DLLs auf dem Computer, auf dem Sie die Anwendung ausführen möchten.

  2. Ein Manifest wird vom Ladeprogramm des Betriebssystems zum Laden von Assemblys verwendet, von denen die Anwendung abhängig ist. Das Manifest kann entweder als Ressource in die Binärdatei eingebettet oder als externe Datei im lokalen Ordner der Anwendung gespeichert sein. Um zu überprüfen, ob das Manifest in die Binärdatei eingebettet ist, öffnen Sie die Binärdatei in Visual Studio, und durchsuchen Sie die Ressourcen in der Binärdatei. Sie sollten eine Ressource mit dem Namen RT_MANIFEST vorfinden. Wenn Sie in der Binärdatei kein eingebettetes Manifest finden, suchen Sie nach einer externen Datei mit einem Namen wie <Name_der_Binärdatei>.<Erweiterung>.manifest.

  3. Wenn kein Manifest vorhanden ist, müssen Sie sicherstellen, dass der Linker ein Manifest für das Projekt generiert. Dazu müssen Sie die Linkeroption Manifest generieren im Dialogfeld Projekteigenschaften des Projekts aktivieren.

    Tipp

    Das Erstellen von Visual C++-Projekten ohne Manifestgenerierung wird nicht unterstützt. Jedes in Visual C++ erstellte C/C++-Programm muss ein Manifest enthalten, das die Abhängigkeiten des Programms von Visual C++-Bibliotheken beschreibt.

  4. Wenn das Manifest in die Binärdatei eingebettet ist, stellen Sie sicher, dass die ID von RT_MANIFEST für diesen Typ von Binärdatei korrekt ist. Für Anwendungen sollte die ID gleich 1, für den Großteil der DLLs gleich 2 sein. Wenn sich das Manifest in einer externen Datei befindet, öffnen Sie es in einem XML-Editor oder einem Texteditor. Weitere Informationen zu Manifesten und Regeln für die Bereitstellung finden Sie unter Manifeste.

    Tipp

    Wenn unter Windows XP ein externes Manifest im lokalen Ordner der Anwendung vorhanden ist, verwendet das Ladeprogramm des Betriebssystems dieses Manifest anstelle eines möglicherweise in der Binärdatei eingebetteten Manifests. Unter Windows Server 2003 und neueren Versionen von Windows ist das Gegenteil der Fall. Das externe Manifest wird ignoriert und stattdessen das eingebettete Manifest verwendet, falls vorhanden.

  5. Es wird für alle DLLs empfohlen, das Manifest in die Binärdatei einzubetten. Externe Manifeste werden ignoriert, wenn eine DLL über einen LoadLibrary-Aufruf geladen wird. Weitere Informationen dazu finden Sie unter Assemblymanifeste.

  6. Stellen Sie sicher, dass alle im Manifest aufgelisteten Assemblys ordnungsgemäß auf dem Computer installiert sind. Für jede Assembly wird im Manifest der Name, die Versionsnummer und die Prozessorarchitektur angegeben. Wenn die Anwendung von parallelen Assemblys abhängig ist, stellen Sie sicher, dass diese Assemblys ordnungsgemäß auf dem Computer installiert sind, sodass sie vom Ladeprogramm des Betriebssystems mithilfe der in Assemblysuchsequenz angegebenen Schritte gefunden werden können. Denken Sie daran, dass 64-Bit-Assemblys nicht in 32-Bit-Prozessen geladen und unter 32-Bit-Betriebssystemen nicht ausgeführt werden können.

Beispiel

Angenommen, die Anwendung appl.exe wurde mit Visual C++ erstellt. Das Manifest dieser Anwendung ist entweder als Binärressource RT_MANIFEST mit der ID 1 in "appl.exe" eingebettet, oder es ist als externe Datei "appl.exe.manifest" gespeichert. Der Inhalt des Manifests kann sich wie folgt zusammensetzen:

<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
  <dependency>
    <dependentAssembly>
      <assemblyIdentity type="win32" name="Microsoft.VC90.CRT" version="9.0.xxxxx.y" processorArchitecture="x86" publicKeyToken="1fc8b3b9a1e18e3b"></assemblyIdentity>
    </dependentAssembly>
  </dependency>
</assembly>

Dieses Manifest teilt dem Ladeprogramm des Betriebssystems mit, dass appl.exe von einer Assembly mit dem Namen Microsoft.VC90.CRT, Version 9.0.xxxxx.y, abhängig ist, die für die 32-Bit-x86-Prozessorarchitektur erstellt wurde.

Die abhängige parallele Assembly kann entweder als freigegebene Assembly oder als private Assembly installiert werden. Visual Studio 2008 installiert die CRT-Assembly z. B. als freigegebene parallele Assembly, die sich unter Windows XP im Verzeichnis "%WINDIR%\WinSxS\x86_Microsoft.VC90.CRT_<Version>" oder unter Windows Vista im Verzeichnis "%WINDIR%\winsxs\x86_microsoft.vc90.crt_<Version>" befindet.

Das assembly manifest für eine freigegebene Visual C++-CRT-Assembly wird entsprechend unter Windows XP in %WINDIR%\WinSxS\Manifests\x86_microsoft.vc90.crt_<version>.manifest oder unter Windows Vista in %WINDIR%\winsxs\Manifests\x86_microsoft.vc90.crt_<version>.manifest installiert. Diese Assembly wird identifiziert und ihr Inhalt aufgelistet (DLLs, die Teil dieser Assembly sind):

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!-- Copyright © 1981-2001 Microsoft Corporation -->
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
   <noInheritable/>
   <assemblyIdentity type="win32" name="Microsoft.VC90.CRT" version="9.0.xxxxx.yy" processorArchitecture="x86" publicKeyToken="1fc8b3b9a1e18e3b"/>
   <file name="msvcr90.dll" hash="3ca5156e8212449db6c622c3d10f37d9adb12c66" hashalg="SHA1"/>
   <file name="msvcp90.dll" hash="92cf8a9bb066aea821d324ca4695c69e55b27cff" hashalg="SHA1"/>
   <file name="msvcm90.dll" hash="7daa93e1195940502491c987ff372190bf199395" hashalg="SHA1"/>
</assembly>

Parallele Assemblys können auch Herausgeberkonfigurationsdateien verwenden (auch Richtliniendateien genannt), um Anwendungen und Assemblys global von der Verwendung einer Version einer parallelen Assembly auf die Verwendung einer anderen Version derselben Assembly umzuleiten. Sie können die Richtlinien für die freigegebene Visual C++-CRT-Assembly unter Windows XP in der Datei %WINDIR%\WinSxS\Policies\x86_policy.9.0.Microsoft.VC90.CRT_<version>.policy und unter Windows Vista in der Datei %WINDIR%\winsxs\Manifests\x86_policy.9.0.microsoft.vc90.crt_<version>.manifest überprüfen. Diese enthält in etwa Folgendes:

</assembly>
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!-- Copyright © 1981-2001 Microsoft Corporation -->
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">

   <assemblyIdentity type="win32-policy" name="policy.9.0.Microsoft.VC90.CRT" version="9.0.xxxxx.yy" processorArchitecture="x86" publicKeyToken="1fc8b3b9a1e18e3b"/>
   <dependency>
      <dependentAssembly>
         <assemblyIdentity type="win32" name="Microsoft.VC90.CRT" processorArchitecture="x86" publicKeyToken="1fc8b3b9a1e18e3b"/>
         <bindingRedirect oldVersion="9.0.aaaaa.bbb-9.0.ccccc.d" newVersion="9.0.xxxxx.yy"/>
      </dependentAssembly>
   </dependency>
</assembly>

Die oben aufgeführte Richtlinie gibt an, dass jede Anwendung oder Assembly, die Version 9.0.aaaaa.bbb dieser Assembly anfordert, stattdessen Version 9.0.xxxxx.yy verwenden soll. Dies ist die aktuelle, auf diesem System installierte Version. Wenn eine Version der Assembly, die im Manifest der Anwendung enthalten ist, in der Richtliniendatei angegeben ist, sucht das Ladeprogramm im Ordner WinSxS nach einer Version dieser im Manifest angegebenen Assembly. Wenn diese Version nicht installiert ist, schlägt das Laden fehl. Wenn die Version 9.0.xxxxx.yy der Assembly ebenfalls nicht installiert ist, schlägt das Laden von Anwendungen fehl, die die Version 9.0.aaaaa.bbb der Assembly anfordern.

Die CRT-Assembly kann jedoch auch als private parallele Assembly im lokalen Ordner der Anwendung installiert werden. Wenn das Betriebssystem die CRT-Assembly oder eine beliebige andere Assembly nicht als freigegebene Assembly finden kann, versucht es, die entsprechende Assembly als private Assembly zu finden. Private Assemblys werden in folgender Reihenfolge gesucht:

  1. Im lokalen Ordner der Anwendung wird nach einem Manifest mit dem Namen <Assemblyname>.manifest gesucht. In diesem Beispiel sucht das Ladeprogramm in demselben Ordner nach "Microsoft.VC90.CRT.manifest", in dem sich auch "appl.exe" befindet. Wenn das Manifest gefunden wird, lädt das Ladeprogramm die CRT-DLL aus dem Anwendungsordner. Wenn die CRT-DLL nicht gefunden wird, schlägt das Laden fehl.

  2. Es wird versucht, den Ordner <Assemblyname> im lokalen Ordner von appl.exe zu öffnen und die Manifestdatei <Assemblyname>.manifest in diesem Ordner zu laden, falls sie existiert. Wenn das Manifest gefunden wird, lädt das Ladeprogramm die CRT-DLL aus dem Ordner <Assemblyname>. Wenn die CRT-DLL nicht gefunden wird, schlägt das Laden fehl.

Eine ausführlichere Beschreibung des Ablaufs der Suche nach abhängigen Assemblys durch das Ladeprogramm finden Sie unter Assemblysuchsequenz. Wenn das Ladeprogramm eine abhängige Assembly nicht als private Assembly finden kann, schlägt das Laden fehl, und es wird die Meldung "Das angegebene Programm kann nicht ausgeführt werden" angezeigt. Um diesen Fehler zu beheben, müssen abhängige Assemblys und DLLs, die Teil dieser Assemblys sind, entweder als private oder als freigegebene Assemblys auf dem Computer installiert werden.

Siehe auch

Konzepte

Konzept der isolierten Anwendungen und der parallelen Assemblys

Weitere Ressourcen

Erstellen von isolierten Anwendungen und parallelen Assemblys (C/C++)