Solucionar problemas de aplicaciones aisladas y ensamblados simultáneos de C/C++

Actualización: noviembre 2007

La acción de cargar una aplicación de C/C++ puede sufrir un error si no se pueden encontrar las bibliotecas de Visual C++ dependientes. Puede encontrar una lista de los posibles errores en tiempo de ejecución en Redistribuir archivos de Visual C++. En esta sección se describen las razones más comunes para que se produzca un error en la carga de una aplicación de C/C++ y se proponen los pasos que se deben seguir para resolver los problemas.

Si se implementa una aplicación en un equipo que no tiene instalado Visual C++ y se bloquea mostrando mensajes de error similares a los descritos en Redistribuir archivos de Visual C++, deben comprobarse varios factores para entender la razón del error.

  1. Siga los pasos descritos en Introducción a las dependencias de una aplicación de Visual C++. Dependency Walker puede mostrar la mayoría de las dependencias de cualquier archivo DLL o aplicación en particular. Si observa que faltan algunos archivos DLL, instálelos en el equipo en el que está intentando ejecutar la aplicación.

  2. El cargador del sistema operativo utiliza un manifiesto para cargar los ensamblados de los que depende la aplicación. El manifiesto se puede incrustar en el binario como un recurso o guardar como un archivo externo en la carpeta local de la aplicación. Para comprobar si el manifiesto está incrustado en el archivo binario, abra el archivo binario en Visual Studio y examine los recursos del mismo. Debería poder encontrar un recurso denominado RT_MANIFEST. Si no puede encontrar un manifiesto incrustado en el binario, busque un archivo externo con una denominación parecida a <nombre_binario>.<extensión>.manifest.

  3. Si no existe un manifiesto, es necesario asegurarse de que el vinculador genere uno para el proyecto. Debe comprobar la opción del vinculador Generar manifiesto en el cuadro de diálogo Propiedades del proyecto para este proyecto.

    Nota:

    No se pueden crear proyectos de Visual C++ sin generación de manifiestos. Los programas de C/C++ generados en Visual C++ 2005 tienen que incluir un manifiesto que describa sus dependencias sobre bibliotecas de Visual C++.

  4. Si el manifiesto está incrustado en el binario, asegúrese de que el identificador de RT_MANIFEST es correcto para este tipo del binario. En el caso de aplicaciones, el identificador debe ser igual a 1 y, para la mayoría de los archivos DLL, debe ser igual a 2. Si el manifiesto está en un archivo externo, ábralo en un editor de texto o en un editor XML. Para obtener más información sobre manifiestos y reglas para la implementación, vea Manifiestos.

    Nota:

    En Windows XP, si hay un manifiesto externo en la carpeta local de la aplicación, el cargador del sistema operativo utiliza este manifiesto en lugar de utilizar un manifiesto incrustado en el binario. En Windows Server 2003 y versiones posteriores de Windows, ocurre lo contrario, es decir, se omite el manifiesto externo y se utiliza el manifiesto incrustado si existe.

  5. Se recomienda que todos los archivos DLL tengan un manifiesto incrustado en el binario. Los manifiestos externos se omiten cuando se carga un archivo DLL mediante una llamada a LoadLibrary. Para obtener más información, vea Manifiestos de ensamblado.

  6. Compruebe que todos los ensamblados enumerados en el manifiesto estén instalados correctamente en el equipo. Cada ensamblado se especifica en el manifiesto por su nombre, el número de versión y la arquitectura del procesador. Si la aplicación depende de ensamblados simultáneos, compruebe que estén instalados correctamente en el equipo para que el cargador del sistema operativo pueda encontrarlos siguiendo los pasos especificados en Secuencia de búsqueda de ensamblados. Recuerde que los ensamblados de 64 bits no se pueden cargar en procesos de 32 bits ni ejecutarse en sistemas operativos de 32 bits.

Ejemplo

Suponga que tenemos una aplicación, appl.exe, generada con Visual C++ 2005. Esta aplicación tiene el manifiesto incrustado en appl.exe como recurso binario RT_MANIFEST con un identificador igual a 1, o almacenado como un archivo externo, appl.exe.manifest. El manifiesto puede tener un contenido similar al siguiente:

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

Para el cargador del sistema operativo, este manifiesto expresa que appl.exe depende de un ensamblado denominado Microsoft.VC90.CRT, versión 9.0.xxxxx.y, y generado para una arquitectura de procesador x86 de 32 bits.

El ensamblado simultáneo dependiente se puede instalar como un ensamblado compartido o como un ensamblado privado. Por ejemplo, Visual Studio 2005 instala el ensamblado CRT como un ensamblado simultáneo compartido que se puede encontrar en el directorio %WINDIR%\WinSxS\x86_Microsoft.VC90.CRT_<versión> al ejecutar Windows XP, o en el directorio %WINDIR%\winsxs\x86_microsoft.vc90.crt_< versión> al ejecutar Windows Vista.

El assembly manifest para un ensamblado de Visual C++ CRT compartido también se instala en %WINDIR%\WinSxS\Manifests\x86_microsoft.vc90.crt_<versión>.manifest al ejecutar Windows XP, o en %WINDIR%\winsxs\Manifests\x86_microsoft.vc90.crt_<versión>.manifest al ejecutar Windows Vista, e identifica este ensamblado y enumera su contenido (archivos DLL que forman parte de este ensamblado):

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

Los ensamblados simultáneos también pueden utilizar archivos de configuración de editor, denominados también archivos de directiva, para redirigir globalmente aplicaciones y ensamblados de una versión de un ensamblado simultáneo a otra versión del mismo ensamblado. Puede comprobar las directivas para el ensamblado de Visual C++ CRT compartido en %WINDIR%\WinSxS\Policies\x86_policy.9.0.Microsoft.VC90.CRT_<versión>.policy al ejecutar Windows XP, o en %WINDIR%\winsxs\Manifests\x86_policy.9.0.microsoft.vc90.crt_<versión>.manifest al ejecutar Windows Vista, que contiene algo como lo siguiente:

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

La directiva anterior especifica que cualquier aplicación o ensamblado que requiere la versión 9.0.aaaaa.bbb de este ensamblado debe utilizar en su lugar la versión 9.0.xxxxx.yy del mismo, que es la versión actual instalada en el sistema. Si se especifica en el archivo de directivas una versión del ensamblado mencionado en el manifiesto de la aplicación, el cargador busca en la carpeta WinSxS una versión de este ensamblado especificado en el manifiesto, y si no está instalada esta versión, la carga sufre un error. Y, si tampoco está instalada la versión 9.0.xxxxx.yy del ensamblado, la carga sufre un error en las aplicaciones que requieren la versión 9.0.aaaaa.bbb del ensamblado.

Sin embargo, el ensamblado CRT también se puede instalar como un ensamblado simultáneo privado en la carpeta local de la aplicación. Si el sistema operativo no encuentra el ensamblado CRT o cualquier otro ensamblado, empieza a buscarlo como un ensamblado privado. La búsqueda de ensamblados privados se realiza en el orden siguiente:

  1. Se busca un archivo de manifiesto con el nombre <nombre_ensamblado>.manifest en la carpeta local de la aplicación. En este ejemplo, el cargador intenta buscar Microsoft.VC90.CRT.manifest en la misma carpeta que appl.exe. Si encuentra el manifiesto, el cargador carga el archivo DLL de CRT desde la carpeta de la aplicación. Si no encuentra el archivo DLL de CRT, la carga sufre un error.

  2. Se intenta abrir la carpeta <nombre_ensamblado> en la carpeta local de appl.exe y, si existe, se carga el archivo del manifiesto <nombre_ensamblado>.manifest de esta carpeta. Si encuentra el manifiesto, el cargador carga el archivo DLL de CRT de la carpeta <nombre_ensamblado>. Si no encuentra el archivo DLL de CRT, la carga sufre un error.

Vea Secuencia de búsqueda de ensamblados para obtener una descripción más detallada de cómo el cargador busca ensamblados dependientes. Si el cargador no encuentra un ensamblado dependiente como ensamblado privado, la carga sufre un error y se muestra el mensaje "El sistema no puede ejecutar el programa especificado". Para solucionar este error, los ensamblados dependientes y los archivos DLL que forman parte de ellos se deben instalar en el equipo como ensamblados privados o compartidos.

Vea también

Conceptos

Conceptos de aplicaciones aisladas y ensamblados simultáneos

Otros recursos

Generar aplicaciones aisladas y ensamblados simultáneos de C/C++