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

La acción de cargar una aplicación de C/C++ puede sufrir un error si no se pueden encontrar las bibliotecas dependientes. En este artículo se describen algunas de las razones comunes por las que una aplicación de C/C++ no se carga y se sugieren pasos para resolver los problemas.

Si una aplicación no puede cargarse porque tiene un manifiesto que especifica una dependencia en un ensamblado en paralelo y ese ensamblado no se instala como ensamblado privado en la misma carpeta que el ejecutable o en la memoria caché de ensamblados nativa en la carpeta %WINDIR%\WinSxS\, puede aparecer uno de los siguientes mensajes de error, según la versión de Windows en la que se intente ejecutar la aplicación.

  • La aplicación podría no inicializarse correctamente (0xc0000135).

  • Error de inicio de la aplicación porque la configuración de la misma no es correcta. Si vuelve a instalar la aplicación, puede que se corrijan los problemas.

  • El sistema no puede ejecutar el programa especificado.

Si la aplicación no tiene ningún manifiesto y depende de un archivo DLL que Windows no puede encontrar en las ubicaciones típicas de búsqueda, puede aparecer un mensaje de error similar al siguiente:

  • No se pudo iniciar la aplicación porque no se encontró una DLL necesaria. La reinstalación de la aplicación puede solucionar el problema.

Si la aplicación se implementa en un equipo que no tiene Visual Studio, se bloquea y muestra mensajes de error similares a los anteriores, compruebe lo siguiente:

  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 una aplicación o de un archivo DLL. 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 el manifiesto de la aplicación para cargar los ensamblados de los que depende la aplicación. El manifiesto se puede incrustar en el binario como un recurso o se puede instalar como un archivo independiente en la carpeta de la aplicación. Para comprobar si el manifiesto está incrustado en el binario, abra el binario en Visual Studio y busque RT_MANIFEST en la lista de recursos que contiene. Si no puede encontrar un manifiesto incrustado, examine la carpeta de aplicaciones de un archivo con un nombre similar a <nombreDebinario>.<extensión>.manifest.

  3. Si la aplicación depende de ensamblados en paralelo y no existe un manifiesto, debe asegurarse de que el vinculador genere uno para el proyecto. Active la opción del vinculador Generar manifiesto en el cuadro de diálogo Propiedades del proyecto correspondiente al proyecto.

  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. Para obtener más información sobre el id. de recurso que debe usar, vea Uso de ensamblados en paralelo como recurso (Windows). Si el manifiesto se encuentra en un archivo independiente, ábralo en un editor XML o en un editor de texto. Para obtener más información sobre los manifiestos y las reglas para la implementación, vea Manifiestos.

    Nota

    Si hay un manifiesto incrustado y un archivo de manifiesto independiente, el cargador del sistema operativo utiliza el manifiesto incrustado y omite el archivo independiente.Sin embargo, en Windows XP, se cumple lo contrario: se usa el archivo de manifiesto independiente y se omite el manifiesto incrustado.

  5. Se recomienda que incruste un manifiesto en cada archivo DLL porque los manifiestos externos se omiten cuando se carga un archivo DLL a través de una llamada a LoadLibrary. Para obtener más información, vea Manifiestos del 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 en paralelo, compruebe que estén instalados correctamente en el equipo para que el cargador del sistema operativo pueda encontrarlos, tal como se describe 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

Supongamos que tenemos una aplicación, appl.exe, que se ha compilado con Visual C++. El manifiesto de la aplicación está incrustado en appl.exe como recurso binario RT_MANIFEST con un identificador igual a 1 o está almacenado como archivo independiente appl.exe.manifest. El contenido de este manifiesto se asemeja a lo siguiente:

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

Para el cargador del sistema operativo, este manifiesto expresa que appl.exe depende de un ensamblado denominado Fabrikam.SxS.Library, versión 2.0.20121.0, compilado para una arquitectura de procesador x86 de 32 bits. El ensamblado en paralelo dependiente se puede instalar como un ensamblado compartido o como un ensamblado privado.

El manifiesto de un ensamblado compartido se instala en la carpeta %WINDIR%\WinSxS\Manifests\. Identifica el ensamblado y muestra su contenido, es decir, los archivos DLL que forman parte del ensamblado:

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

Los ensamblados en paralelo también pueden utilizar archivos de configuración de editor, denominados también archivos de directiva, para redirigir globalmente las aplicaciones y los ensamblados a una versión de un ensamblado en paralelo, en lugar de que usen otra versión del mismo ensamblado. Puede comprobar las directivas para un ensamblado compartido en la carpeta %WINDIR%\WinSxS\Policies\. A continuación se muestra un archivo de directivas del ejemplo:

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

Este archivo de directivas especifica que cualquier aplicación o ensamblado que requiera la versión 2.0.10000.0 de este ensamblado debe utilizar en su lugar la versión 2.0.20121.0, 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 %WINDIR%\WinSxS\ una versión de este ensamblado especificada en el manifiesto y si no está instalada esa versión, la carga sufre un error. Si la versión 2.0.20121.0 del ensamblado no está instalada, la carga sufre un error en las aplicaciones que requieren la versión 2.0.10000.0 del ensamblado.

Sin embargo, el ensamblado también se puede instalar como un ensamblado en paralelo privado en la carpeta de la aplicación instalada. Si el sistema operativo no encuentra el ensamblado como ensamblado compartido, lo busca como ensamblado privado, en el orden siguiente:

  1. Busca un archivo de manifiesto denominado <nombreDeEnsamblado>.manifest en la carpeta de la aplicación. En este ejemplo, el cargador intenta buscar Fabrikam.SxS.Library.manifest en la carpeta que contiene appl.exe. Si encuentra el manifiesto, el cargador carga el ensamblado desde la carpeta de la aplicación. Si no se encuentra el ensamblado, la carga sufre un error.

  2. Intente abrir la carpeta \<nombreDeEnsamblado>\ en la carpeta que contiene appl.exe y, si \<nombreDeEnsamblado>\ existe, intente cargar un archivo de manifiesto denominado <nombreDeEnsamblado>.manifest desde esta carpeta. Si se encuentra el manifiesto, el cargador carga el ensamblado desde la carpeta \<nombreDeEnsamblado>\. Si no se encuentra el ensamblado, la carga sufre un error.

Para obtener más información sobre cómo el cargador busca ensamblados dependientes, vea Secuencia de búsqueda de ensamblados. 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, asegúrese de que los ensamblados dependientes, y los archivos DLL que forman parte de ellos, estén instalados en el equipo como ensamblados privados o compartidos.

Vea también

Conceptos

Conceptos de aplicaciones aisladas y ensamblados simultáneos

Otros recursos

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