Risoluzione dei problemi relativi alle applicazioni isolate C/C++ e agli assembly side-by-side

Il caricamento di un'applicazione C/C++ può avere esito negativo se non è possibile trovare le librerie di Visual C++ dipendenti. Per un elenco di errori di runtime potenziali, vedere Ridistribuzione di file Visual C++. In questa sezione vengono descritte le ragioni più comuni del mancato caricamento di un'applicazione C/C++ con le relative soluzioni.

Se un'applicazione viene distribuita in un computer in cui non è installato Visual C++ e si blocca con messaggi di errore simili a quelli elencati in Ridistribuzione di file Visual C++, è necessario controllare diverse cose per capire la ragione dell'errore.

  1. Eseguire i passaggi illustrati in Utilizzo di dipendenze di un'applicazione Visual C++. Tramite Dependency Walker è possibile visualizzare la maggior parte delle dipendenze per qualsiasi applicazione o DLL specifica. Se alcune DLL risultano mancanti, installare queste DLL nel computer in cui si sta tentando di eseguire l'applicazione.

  2. Un manifesto viene utilizzato dal caricatore del sistema operativo per caricare gli assembly da cui dipende l'applicazione. Tale manifesto può essere incorporato nel binario come risorsa, oppure salvato come file esterno nella cartella locale dell'applicazione. Per controllare se il manifesto è incorporato nel binario, aprire il binario in Visual Studio e cercare tra le risorse di tale binario. Dovrebbe essere possibile trovare una risorsa denominata RT_MANIFEST. Se non è possibile trovare un manifesto incorporato all'interno del file binario, verificare la presenza di un file esterno con una denominazione simile a <binary_name>.<extension>.manifest.

  3. Se non è presente alcun manifesto, è necessario assicurarsi che il linker generi un manifesto per il progetto. A tale scopo, verificare l'opzione del linker Genera manifesto nella finestra di dialogo Proprietà progetto per questo progetto.

    Nota

    La compilazione di progetti Visual C++ senza generazione del manifesto non è supportata. Qualsiasi programma C/C++ compilato in Visual C++ deve includere un manifesto che ne descriva le dipendenze dalle librerie di Visual C++.

  4. Se il manifesto è incorporato all'interno del file binario, assicurarsi che l'ID di RT_MANIFEST sia corretto per questo tipo di file binario. Per le applicazioni, l'ID deve essere uguale a 1, per la maggior parte delle DLL l'ID deve essere uguale a 2. Se il manifesto è in un file esterno, aprirlo in un editor XML o in un editor di testo. Per ulteriori informazioni sui manifesti e sulle regole di distribuzione, vedere manifesti.

    Nota

    In Windows XP, se nella cartella locale dell'applicazione è presente un manifesto esterno, il caricatore del sistema operativo utilizzerà tale manifesto invece di un manifesto incorporato all'interno del file binario. In Windows Server 2003 e le versioni successive di Windows, si verifica la situazione opposta, ovvero viene ignorato il manifesto esterno e viene utilizzato il manifesto incorporato, se presente.

  5. È consigliabile che tutte le DLL dispongano di un manifesto incorporato all'interno del file binario. I manifesti esterni vengono ignorati quando una DLL viene caricata tramite una chiamata a LoadLibrary. Per ulteriori informazioni, vedere manifesti dell'assembly.

  6. Verificare che tutti gli assembly enumerati nel manifesto siano installati correttamente nel computer. Ogni assembly viene specificato nel manifesto secondo il nome, il numero di versione e l'architettura del processore. Se l'applicazione dipende da assembly side-by-side, verificare che tali assembly siano installati correttamente nel computer, in modo da poter essere trovati dal caricatore del sistema operativo tramite i passaggi specificati in Assembly Searching Sequence. Si ricordi che gli assembly a 64 bit non possono essere caricati in processi a 32 bit e non possono essere eseguiti in sistemi operativi a 32 bit.

Esempio

Si presupponga di disporre di un'applicazione, appl.exe, compilata con Visual C++. Questa applicazione dispone sia di un manifesto incorporato all'interno di appl.exe come risorsa binaria RT_MANIFEST con ID uguale a 1, sia di un manifesto archiviato come file esterno, appl.exe.manifest. Il contenuto del manifesto potrebbe essere simile a quanto riportato di seguito:

<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>

Questo manifesto indica al caricatore del sistema operativo che appl.exe dipende da un assembly denominato Microsoft.VC90.CRT, versione 9.0.xxxxx.y e compilato per un'architettura del processore x86 a 32 bit.

L'assembly side-by-side dipendente può essere installato come assembly condiviso o come assembly privato. Ad esempio, Visual Studio 2008 installa l'assembly CRT come un assembly side-by-side condiviso che è disponibile nella directory %WINDIR%\WinSxS\x86_Microsoft.VC90.CRT_<versione> se è in esecuzione Windows XP o nella directory %WINDIR%\winsxs\x86_microsoft.vc90.crt_<versione> se è in esecuzione Windows Vista.

L'assembly manifest per un assembly Visual C++ CRT condiviso è installato anche in %WINDIR%\WinSxS\Manifests\x86_microsoft.vc90.crt_<versione>.manifest quando è in esecuzione Windows XP o in %WINDIR%\winsxs\Manifests\x86_microsoft.vc90.crt_<versione>.manifest quando è in esecuzione Windows Vista ed identifica questo assembly ed elenca il contenuto (DLL che fanno parte di questo 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">
   <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>

Gli assembly side-by-side possono inoltre utilizzare i file di configurazione dell'editore, denominati anche file di criteri, per reindirizzare a livello globale le applicazioni e gli assembly dall'utilizzo di una versione di un assembly side-by-side a un'altra versione dello stesso assembly. È possibile verificare i criteri dell'assembly Visual C++ CRT condiviso in %WINDIR%\WinSxS\Policies\x86_policy.9.0.Microsoft.VC90.CRT_<versione>.policy quando è in esecuzione Windows XP o in %WINDIR%\winsxs\Manifests\x86_policy.9.0.microsoft.vc90.crt_<versione>.manifest quando è in esecuzione Windows Vista, in cui sono contenuti elementi simili a quelli riportati di seguito:

</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>

I criteri indicati in precedenza specificano che qualsiasi applicazione o assembly che richiede la versione 9.0.aaaaa.bbb di questo assembly deve invece utilizzare la versione 9.0.xxxxx.yy di questo assembly, ovvero la versione attualmente installata nel sistema. Se nel file di criteri viene specificata una versione dell'assembly indicato nel manifesto dell'applicazione, il caricatore cercherà una versione di questo assembly specificato nel manifesto nella cartella WinSxS, e se tale versione non è installata, il caricamento avrà esito negativo. Anche nel caso in cui non sia installata una versione di assembly 9.0.xxxxx.yy, il caricamento avrà esito negativo per le applicazioni che richiedono una versione di assembly 9.0.aaaaa.bbb.

L'assembly CRT può anche essere installato come assembly side-by-side privato nella cartella locale dell'applicazione. Se il sistema operativo non è in grado di trovare l'assembly CRT o qualsiasi altro assembly come assembly condiviso, inizierà la ricerca dell'assembly come assembly privato. La ricerca di assembly privati viene eseguita nell'ordine riportato di seguito:

  1. Viene controllata la cartella locale dell'applicazione per verificare la presenza di un file manifesto denominato <assemblyName>.manifest. In questo esempio, il caricatore cerca di trovare Microsoft.VC90.CRT.manifest nella stessa cartella di appl.exe. Se il manifesto viene trovato, il caricatore caricherà la DLL CRT dalla cartella dell'applicazione. Se la DLL CRT non viene trovata, il caricamento avrà esito negativo.

  2. Si tenta di aprire la cartella <assemblyName> nella cartella locale di appl.exe e, se presente, si carica il file manifesto <assemblyName>.manifest da questa cartella. Se il manifesto viene trovato, il caricatore caricherà la DLL CRT dalla cartella <assemblyName>. Se la DLL CRT non viene trovata, il caricamento avrà esito negativo.

Per una descrizione più dettagliata delle modalità di ricerca degli assembly dipendenti da parte del caricatore, vedere Assembly Searching Sequence. Se il caricatore non è in grado di trovare un assembly dipendente come assembly privato, il caricamento avrà esito negativo e verrà visualizzato il messaggio "Impossibile eseguire il programma specificato". Per correggere questo errore, è necessario che gli assembly dipendenti e le DLL che li compongono siano installati nel computer come assembly privati o condivisi.

Vedere anche

Concetti

Concetti di applicazioni isolate e assembly side-by-side

Altre risorse

Compilazione di applicazioni isolate C/C++ e di assembly side-by-side