dll order manifest msvcrt loadlibrary

LoadLibrary() no puede cargar DLL con manifiesto y ensamblado privado



order manifest (2)

Enlace estático con el CRT. Siempre que no use .Net en su aplicación (C / C ++ puro) es posible vincular estáticamente con el CRT.

La introducción de .Net en mi aplicación me obligó a pasar de un CRT estáticamente vinculado a un CRT enlazado dinámicamente. También traté de encontrar una forma de referirme a las DLL de CRT localmente sin la necesidad de instalarlas explícitamente, pero no las encontré. Por lo tanto, si es posible, enlace estáticamente con el CRT.

Estoy trabajando en una aplicación de Windows (EXE) que usa varias DLL. El desarrollo está en VCExpress 2005 (VC 8.0), usando solo C.

Algunas de estas DLL son complementos / complementos / extensiones que se cargan dinámicamente utilizando LoadLibrary acuerdo con un archivo de configuración leído por el EXE.

Es importante destacar que la aplicación debe ser portátil (en el sentido de poder ejecutarse desde una unidad flash USB o similar sin instalación), y las DLL de plug-in pueden no estar en la misma carpeta que la aplicación EXE (razones heredadas).

Con MSVC6 esto es sencillo: compilar, vincular, distribuir EXE y DLL.

Con MSVC8, la biblioteca C Runtime Library (MSVCRT) ya no se distribuye con el sistema operativo, por lo que no se puede confiar en su instalación. Para satisfacer el requisito de portabilidad, necesito usar un ensamblaje privado . Todos los EXEs y DLL han incorporado sus manifiestos.

Mi problema : los archivos DLL de plug-in cargados a través de LoadLibrary() no encuentran el ensamblado privado que está en la carpeta del EXE, por lo que intentar cargarlos falla a menos que el ensamblado Microsoft.VC80.CRT esté instalado en winSxS.

El truco : si los manifiestos se eliminan de las DLL de plug-in, todo funciona.

Mis preguntas :

  1. En el caso del problema, Windows no parece estar siguiendo la secuencia de búsqueda de conjunto o el orden de búsqueda de la biblioteca de enlace dinámico . Específicamente, busca el ensamblado privado en la ruta desde la que se cargó el archivo DLL, no desde el que se cargó la aplicación (EXE).
    Intenté verificar esto colocando el ensamblaje junto a la DLL y cambiando el directorio actual (para descartarlo relacionado con casos de directorio de trabajo) y obtengo el comportamiento esperado. ¿Alguien más puede confirmar que este es el comportamiento normal al usar LoadLibrary con SxS?

  2. ¿Estoy en lo cierto al suponer que sin un manifiesto, la DLL vuelve a la orden de carga no SxS que encuentra msvcr80.dll (en lugar del manifiesto de ensamblado Microsoft.VC80.CRT.manifest ) en la carpeta del EXE?

  3. Si estoy en lo cierto acerca de (1) y (2), ¿qué pierdo simplemente excluyendo el manifiesto de la DLL? Reformulado, ¿por qué no debería resolver mi problema simplemente excluyendo el manifiesto?


Necesita comprender qué es un contexto de activación para comprender este problema.

Un exe, o dll, con un manifiesto, tiene un contexto de activación: el contexto de activación es una lista de clases de ventana, conjuntos dependientes, dlls y referencias de comisionamiento gratuitas de registro que se descubrieron cuando se analizó el manifiesto.

Un exe, o dll, sin manifiesto, utiliza el contexto de activación predeterminado del proceso, que generalmente es el contexto de activación del exe si el exe tiene un contexto de activación.

En su caso, el dll tiene su propio contexto de activación, porque tiene un manifiesto. Y siempre es la ruta al (archivo / carpeta que contiene el) archivo de manifiesto que se busca ensamblados.

Por eso windows comienza buscando en la carpeta del dll para el ensamblado privado. Luego, cuando eso falla, Windows busca en la ruta de búsqueda de la biblioteca de carga estándar para el dll: que comienza con la carpeta raíz del ejecutable. Pero está buscando dll ahora, NO ensambles, por lo que no se encuentra la carpeta de ensamblaje que contiene el dll.

  1. No. Sin un manifiesto, el dll vuelve a utilizar el contexto de activación predeterminado: el manifiesto del exe. Este artículo del blog lo explica un poco.

  2. Excluir el manifiesto Lo que pierde es la capacidad de conseguir que el dll especifique sus propios ensamblajes dependientes. Lo que debe hacer, por lo tanto, es agregar cualquier ensamblaje dependiente que necesite el dll al manifiesto de la aplicación.