Rozwiązywanie problemów związanych z aplikacjami izolowanymi C/C++ oraz aplikacjami wykonywanymi równocześnie

Ładowanie aplikacji C/C++ może zakończyć się niepowodzeniem, jeśli nie można odnaleźć bibliotek zależnych. W tym artykule opisano niektóre typowe przyczyny niepowodzenia ładowania aplikacji C/C++ i sugeruje kroki rozwiązywania problemów.

Jeśli ładowanie aplikacji nie powiedzie się, ponieważ ma manifest określający zależność od zestawu równoległego, a zestaw nie jest zainstalowany jako zestaw prywatny w tym samym folderze co plik wykonywalny ani w natywnej pamięci podręcznej zestawów w folderze %WINDIR%\WinSxS\, może zostać wyświetlony jeden z następujących komunikatów o błędach, w zależności od wersji systemu Windows, na której próbujesz uruchomić aplikację.

  • Nie można poprawnie zainicjować aplikacji (0xc0000135).

  • Nie można uruchomić tej aplikacji, ponieważ konfiguracja aplikacji jest niepoprawna. Ponowne zainstalowanie aplikacji może rozwiązać ten problem.

  • System nie może wykonać określonego programu.

Jeśli aplikacja nie ma manifestu i zależy od biblioteki DLL, której system Windows nie może znaleźć w typowych lokalizacjach wyszukiwania, może zostać wyświetlony komunikat o błędzie podobny do następującego:

  • Nie można uruchomić tej aplikacji, ponieważ nie znaleziono wymaganej biblioteki DLL . Ponowne zainstalowanie aplikacji może rozwiązać ten problem.

Jeśli aplikacja jest wdrażana na komputerze, który nie ma programu Visual Studio i ulega awarii z komunikatami o błędach podobnymi do poprzednich, sprawdź następujące elementy:

  1. Wykonaj kroki opisane w artykule Understanding the Dependencies of a Visual C++ Application (Opis zależności aplikacji Visual C++). Przewodnik zależności może pokazywać większość zależności dla aplikacji lub biblioteki DLL. Jeśli zauważysz, że brakuje niektórych bibliotek DLL, zainstaluj je na komputerze, na którym próbujesz uruchomić aplikację.

  2. Moduł ładujący systemu operacyjnego używa manifestu aplikacji do ładowania zestawów, od których zależy aplikacja. Manifest może być osadzony w pliku binarnym jako zasób lub zainstalowany jako oddzielny plik w folderze aplikacji. Aby sprawdzić, czy manifest jest osadzony w pliku binarnym, otwórz plik binarny w programie Visual Studio i poszukaj RT_MANIFEST na liście zasobów. Jeśli nie możesz znaleźć osadzonego manifestu, poszukaj w folderze aplikacji pliku o nazwie podobnej do <binary_name>.<extension.manifest>.

  3. Jeśli aplikacja zależy od zestawów równoległych i manifest nie jest obecny, musisz upewnić się, że konsolidator generuje manifest dla projektu. Zaznacz opcję konsolidatora Wygeneruj manifest w oknie dialogowym Właściwości projektu dla projektu.

  4. Jeśli manifest jest osadzony w pliku binarnym, upewnij się, że identyfikator RT_MANIFEST jest poprawny dla tego typu pliku binarnego. Aby uzyskać więcej informacji na temat identyfikatora zasobu do użycia, zobacz Używanie zestawów równoległych jako zasobu (Windows). Jeśli manifest znajduje się w osobnym pliku, otwórz go w edytorze XML lub edytorze tekstów. Aby uzyskać więcej informacji na temat manifestów i reguł wdrażania, zobacz Manifesty.

    Uwaga

    Jeśli istnieje zarówno osadzony manifest, jak i oddzielny plik manifestu, moduł ładujący systemu operacyjnego używa osadzonego manifestu i ignoruje oddzielny plik. Jednak w systemie Windows XP odwrotnie jest prawdziwe — używany jest oddzielny plik manifestu, a osadzony manifest jest ignorowany.

  5. Zalecamy osadzanie manifestu w każdej dll, ponieważ manifesty zewnętrzne są ignorowane, gdy biblioteka DLL jest ładowana przez LoadLibrary wywołanie. Aby uzyskać więcej informacji, zobacz Manifesty zestawów.

  6. Sprawdź, czy wszystkie zestawy, które są wyliczane w manifeście, są poprawnie zainstalowane na komputerze. Każdy zestaw jest określony w manifeście według jego nazwy, numeru wersji i architektury procesora. Jeśli aplikacja zależy od zestawów równoległych, sprawdź, czy te zestawy są poprawnie zainstalowane na komputerze, aby moduł ładujący systemu operacyjnego mógł je znaleźć zgodnie z opisem w sekcji Sekwencja wyszukiwania zestawów. Pamiętaj, że zestawy 64-bitowe nie mogą być ładowane w 32-bitowych procesach i nie można ich wykonywać w 32-bitowych systemach operacyjnych.

Przykład

Załóżmy, że mamy aplikację appl.exe, która została skompilowana przy użyciu języka Visual C++. Manifest aplikacji jest osadzony w pliku appl.exe jako zasób binarny RT_MANIFEST, który ma identyfikator równy 1, lub jest przechowywany jako oddzielny plik appl.exe.manifest. Zawartość tego manifestu przypomina następującą:

<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
  <dependency>
    <dependentAssembly>
      <assemblyIdentity type="win32" name="Fabrikam.SxS.Library" version="2.0.20121.0" processorArchitecture="x86" publicKeyToken="1fc8b3b9a1e18e3e"></assemblyIdentity>
    </dependentAssembly>
  </dependency>
</assembly>

Do modułu ładującego systemu operacyjnego ten manifest mówi, że plik appl.exe zależy od zestawu o nazwie Fabrikam.SxS.Library w wersji 2.0.20121.0, który został utworzony dla 32-bitowej architektury procesora x86. Zależny zestaw równoległy można zainstalować jako zestaw udostępniony lub jako zestaw prywatny.

Manifest zestawu udostępnionego jest instalowany w folderze %WINDIR%\WinSxS\Manifests\. Identyfikuje zestaw i wyświetla jego zawartość — czyli biblioteki DLL będące częścią zestawu:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
   <noInheritable/>
   <assemblyIdentity type="win32" name="Fabrikam.SxS.Library" version="2.0.20121.0" processorArchitecture="x86" publicKeyToken="1fc8b3b9a1e18e3e"/>
   <file name="Fabrikam.Main.dll" hash="3ca5156e8212449db6c622c3d10f37d9adb1ab12" hashalg="SHA1"/>
   <file name="Fabrikam.Helper.dll" hash="92cf8a9bb066aea821d324ca4695c69e55b2d1c2" hashalg="SHA1"/>
</assembly>

Zestawy równoległe mogą również używać plików konfiguracji wydawcy , nazywanych również plikami zasad, aby globalnie przekierowywać aplikacje i zestawy do używania jednej wersji zestawu równoległego zamiast innej wersji tego samego zestawu. Zasady dla zestawu udostępnionego można sprawdzić w folderze %WINDIR%\WinSxS\Policies\. Oto przykładowy plik zasad:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">

   <assemblyIdentity type="win32-policy" name="policy.2.0.Fabrikam.SxS.Library" version="2.0.20121.0" processorArchitecture="x86" publicKeyToken="1fc8b3b9a1e18e3e"/>
   <dependency>
      <dependentAssembly>
         <assemblyIdentity type="win32" name="Fabrikam.SxS.Library" processorArchitecture="x86" publicKeyToken="1fc8b3b9a1e18e3e"/>
         <bindingRedirect oldVersion="2.0.10000.0-2.0.20120.99" newVersion="2.0.20121.0"/>
      </dependentAssembly>
   </dependency>
</assembly>

Ten plik zasad określa, że każda aplikacja lub zestaw, który prosi o wersję 2.0.10000.0 tego zestawu, powinien zamiast tego używać wersji 2.0.20121.0, która jest bieżącą wersją zainstalowaną w systemie. Jeśli w pliku zasad zostanie określona wersja zestawu wymienionego w manifeście aplikacji, moduł ładujący szuka wersji tego zestawu określonego w manifeście w folderze %WINDIR%\WinSxS\, a jeśli ta wersja nie jest zainstalowana, ładowanie zakończy się niepowodzeniem. Jeśli zestaw w wersji 2.0.20121.0 nie jest zainstalowany, ładowanie nie powiedzie się w przypadku aplikacji, które proszą o zestaw w wersji 2.0.10000.0.

Zestaw można jednak również zainstalować jako prywatny zestaw równoległy w zainstalowanym folderze aplikacji. Jeśli system operacyjny nie może odnaleźć zestawu jako zestawu udostępnionego, szuka go jako zestawu prywatnego w następującej kolejności:

  1. Sprawdź folder aplikacji dla pliku manifestu o nazwie <assemblyName.manifest>. W tym przykładzie moduł ładujący próbuje znaleźć plik Fabrikam.SxS.Library.manifest w folderze zawierającym plik appl.exe. Jeśli znajdzie manifest, moduł ładujący ładuje zestaw z folderu aplikacji. Jeśli zestaw nie zostanie znaleziony, ładowanie zakończy się niepowodzeniem.

  2. Spróbuj otworzyć folder \<assemblyName>\ w folderze zawierającym plik appl.exe, a jeśli plik \<assemblyName>\ istnieje, spróbuj załadować plik manifestu o nazwie <assemblyName.manifest> z tego folderu. Jeśli manifest zostanie znaleziony, moduł ładujący ładuje zestaw z folderu \<assemblyName>\. Jeśli zestaw nie zostanie znaleziony, ładowanie zakończy się niepowodzeniem.

Aby uzyskać więcej informacji na temat wyszukiwania zestawów zależnych przez moduł ładujący, zobacz Sekwencja wyszukiwania zestawów. Jeśli moduł ładujący nie może odnaleźć zestawu zależnego jako zestawu prywatnego, ładowanie zakończy się niepowodzeniem, a zostanie wyświetlony komunikat "System nie może wykonać określonego programu". Aby rozwiązać ten problem, upewnij się, że zależne zestawy i biblioteki DLL, które są ich częścią, są instalowane na komputerze jako zestawy prywatne lub udostępnione.

Zobacz też

Pojęcia związane z aplikacjami izolowanymi oraz aplikacjami wykonywanymi równocześnie
Kompilowanie aplikacji izolowanych C/C++ oraz aplikacji wykonywanych równocześnie