No se puede cargar la DLL (no se pudo encontrar el módulo HRESULT: 0x8007007E)

113

Tengo una biblioteca dll con código API C ++ no administrado que necesito usar en mi aplicación .NET 4.0. Pero cada método que intento cargar mi dll me sale un error:

No se puede cargar la DLL 'MyOwn.dll': no ​​se pudo encontrar el módulo especificado. (Excepción de HRESULT: 0x8007007E)

He leído y probado varias soluciones que he encontrado en Internet. Nada funciona..

He intentado utilizar los siguientes métodos:

[DllImport("MyOwn.dll",  CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAs((UnmanagedType.I4))]
public static extern Int32 MyProIni(string DBname, string DBuser_pass,
    string WorkDirectory, ref StringBuilder ErrorMessage);

Cuando intenté seguir este artículo y cuando ejecuto este ejemplo (del código descargado) se ejecuta sin problemas (el dll utilizado está en la carpeta bin / debug)

He copiado mi dll (junto con todos los archivos de los que depende en mi carpeta bin).

También probé este enfoque pero obtuve el mismo error:

[DllImportAttribute(MyOwnLibDllPath, EntryPoint="TMproIni")]
[return: MarshalAs(UnmanagedType.I4)]
public static extern  int MyproIni(string DBname, string DBuser_pass, 
    string WorkDirectory, ref StringBuilder ErrorMessage);

¿Alguna sugerencia?

Ingimar Andresson
fuente

Respuestas:

90

Por lo que recuerdo en Windows, el orden de búsqueda de una dll es:

  1. Directorio actual
  2. Carpeta del sistema C:\windows\system32 or c:\windows\SysWOW64(para procesos de 32 bits en cajas de 64 bits).
  3. Leer de la Pathvariable de entorno

Además, verificaría las dependencias de la DLL, el analizador de dependencias proporcionado con Visual Studio puede ayudarlo aquí, también se puede descargar de forma gratuita: http://www.dependencywalker.com

display101
fuente
4
encontró que faltaba alguna dependencia (Oracle y algunos dll de IE). Necesito instalar Oracle ya que mi dll depende de eso ... entonces lo sabré :) Encontré el problema con DependencyWalker;)
Ingimar Andresson
No se preocupe, me ha ahorrado muchas horas de rascarse la cabeza, ¡una gran herramienta! :-)
display101
1
+1 a Keith Halligan por sugerir DependencyWalker. Me dijo que no todas las dependencias tenían el mismo tipo de CPU (x86 / x64). Copié todos los archivos que tenían el mismo tipo de CPU en la carpeta bin de mi aplicación y eso resolvió el problema.
DiligentKarma
6
Cada dll que puedo encontrar en mi sistema tiene DependencyWalker afirmando que hay un error con diferentes tipos de CPU, incluso System.Web.Mvc.dll. Hay una especie de falsa alarma aquí.
PandaWood
2
En mi caso, el problema fue intentar cargar una DLL de C ++ compilada para Debug. Eso necesita el tiempo de ejecución de depuración de C ++, lo que significa que debe instalar Visual Studio. O vuelva a compilar la DLL para su lanzamiento e instale el tiempo de ejecución de C ++ distribuible.
RenniePet
42

Puede utilizar la herramienta dumpbin para averiguar las dependencias DLL necesarias:

dumpbin /DEPENDENTS my.dll

Esto le dirá qué DLL necesita cargar su DLL. En particular, busque MSVCR * .dll. He visto que su código de error se produce cuando el Visual C ++ Redistributable correcto no está instalado.

Puede obtener los "Paquetes redistribuibles de Visual C ++ para Visual Studio 2013" en el sitio web de Microsoft. Instala c: \ windows \ system32 \ MSVCR120.dll

En el nombre del archivo, 120 = 12.0 = Visual Studio 2013.

Tenga cuidado de tener la versión correcta de Visual Studio (10.0 = VS 10, 11 = VS 2012, 12.0 = VS 2013 ...) arquitectura adecuada (x64 o x86) para la plataforma de destino de su DLL, y también debe tener cuidado con depurar compilaciones. La compilación de depuración de una DLL depende de MSVCR120d.dll, que es una versión de depuración de la biblioteca, que se instala con Visual Studio pero no con el paquete redistribuible.

Anthony Hayward
fuente
5
¡Agregar los redistribuibles VS C ++ fue para mí! necesita v10.0 (2010). Muchas gracias !!!
Thiago Silva
¿Hay alguna forma de saber si se requieren versiones de 64 bits o de 32 bits de los redistribuibles?
BVB
1
dumpbin / ALL le dirá si my.dll es x86 o x64
Anthony Hayward
1
Para aquellos que todavía padecen este problema, si usa debugbinario, la versión de los redistribuibles en tiempo de ejecución de C ++ debe ser exactamente la misma que donde la construyó.
skyline75489
El comentario de @ skyline75489 me salvó el día. La biblioteca C ++ funcionó bien en mi máquina, pero no se pudo cargar en cualquier otro lugar debido a que VS la vinculaba a la versión de depuración de msvcr.
espía
14

Esto es un 'kludge' pero al menos podría usarlo para probar la cordura: intente codificar la ruta a la DLL en su código

[DllImport(@"C:\\mycompany\\MyDLL.dll")]

Una vez dicho esto; en mi caso, ejecutar dumpbin /DEPENDENTScomo lo sugiere @ anthony-hayward, y copiar más de las versiones de 32 bits de las DLL enumeradas allí en mi directorio de trabajo resolvió este problema para mí.

El mensaje es un poco engañoso, porque no es "mi" dll que no se puede cargar, son las dependencias

Negro
fuente
12

La DLL debe estar en la carpeta bin.

En Visual Studio, agrego el dll a mi proyecto (NO en Referencias, sino en "Agregar archivo existente"). Luego, establezca la propiedad "Copiar en el directorio de salida" de la dll en "Copiar si es más reciente".

Jeremy Thompson
fuente
11

Intente ingresar la ruta completa de la dll. Si no funciona, intente copiar el dll en la carpeta system32.

Headpuster
fuente
3
¿Está bien tener todas las dependencias en la carpeta System32 y mi dll en otro lugar?
Ingimar Andresson
Las dependencias también se buscarán según el orden de la ruta de búsqueda de Windows dll según lo especificado por stackoverflow.com/a/9003290/4434329
4

Asegúrese de que todas las dependencias de su propia dll estén presentes cerca de la dll o en System32.

Felice Pollano
fuente
4

Hay una cosa muy divertida (y tiene una relevancia técnica) que podría desperdiciar sus horas, así que pensó en compartirla aquí:

Creé un proyecto de aplicación de consola ConsoleApplication1y un proyecto de biblioteca de clases.ClassLibrary1 .

Todo el código que estaba haciendo p / invoke estaba presente en ClassLibrary1.dll. Entonces, antes de depurar la aplicación desde Visual Studio, simplemente copié el ensamblado no administrado de C ++ ( myUnmanagedFunctions.dll) en el \bin\debug\directorio del ClassLibrary1proyecto para que CLR pueda cargarlo en tiempo de ejecución.

Seguí recibiendo el

No se puede cargar la DLL

error durante horas. Más tarde me di cuenta de que todos los ensamblados no administrados que se van a cargar deben copiarse en el \bin\debugdirectorio del proyecto de inicio, ConsoleApplication1que generalmente es un formulario win, una consola o una aplicación web.

Por lo tanto, tenga cuidado de que Current Directoryen la respuesta aceptada en realidad significa el Current Directoryejecutable principal desde donde se inicia el proceso de aplicación. Parece algo obvio, pero a veces puede que no lo sea.

Lección aprendida : coloque siempre las DLL no administradas en el mismo directorio que el ejecutable de inicio para asegurarse de que se puedan encontrar.

RBT
fuente
Esto también solucionó las cosas para mí. Sin embargo, se siente un poco extraño poner los archivos DLL en el proyecto principal en lugar del proyecto que realmente los usa ...
Sean Duggan
@SeanDuggan eso se debe a que es una "biblioteca de vinculación dinámica", lo que significa que se usa (se carga) en tiempo de ejecución en lugar de las bibliotecas estáticas que se usan en el tiempo de vinculación.
m4l490n
He intentado agregar el archivo DLL en el bin\Debugy los obj\Debugdirectorios y me siguen dando el "No se puede DLL de carga"
m4l490n
3

Active el registro de fusión, consulte esta pregunta para obtener muchos consejos sobre cómo hacerlo. La depuración de problemas de carga de aplicaciones de modo mixto puede ser un verdadero dolor de cabeza. El registro de fusión puede ser de gran ayuda.

Chris O
fuente
2

Asegúrese de configurar Build Platform Target en x86 o x64 para que sea compatible con su DLL, que podría estar compilado para una plataforma de 32 bits.

Grantly
fuente
2

Si los proyectos DLL y .NET están en la misma solución y desea compilar y ejecutar ambos cada vez, puede hacer clic con el botón derecho en las propiedades del proyecto .NET, Eventos de compilación y luego agregar algo como lo siguiente al evento posterior a la compilación línea de comando:

copy $(SolutionDir)Debug\MyOwn.dll .

Básicamente es una línea de DOS, y puede ajustar según dónde se construya su DLL.

SharpC
fuente
2

Tuve el mismo problema cuando implementé mi aplicación para probar la PC. El problema era que la PC de desarrollo tenía msvcp110d.dllymsvcr110d.dll pero no el PC de prueba.

Agregué el módulo de combinación "Visual Studio C ++ 11.0 DebugCRT (x86)" en InstalledSheild y funcionó. Espero que esto sea útil para otra persona.

kakopappa
fuente
2

En mi caso, una dll no administrada dependía de otra que faltaba. En ese caso, el error apuntará a la dll existente en lugar de la que falta, lo que puede ser realmente confuso.

Eso es exactamente lo que sucedió en mi caso. Espero que esto ayude a alguien más.

Rahatur
fuente
1

Creo que su biblioteca no administrada necesita un manifiesto.
Aquí se explica cómo agregarlo a su binario. y aqui por qué.

En resumen, se pueden instalar varias versiones de la biblioteca redistribuible en su caja, pero solo una de ellas debería satisfacer su aplicación, y puede que no sea la predeterminada, por lo que debe indicarle al sistema la versión que necesita su biblioteca, por eso el manifiesto.

Eugenio Miró
fuente
1

Configuración : Windows 7 de 32 bits

Contexto : instalé un controlador PCI-GPIB con el que no pude comunicarme debido al problema mencionado anteriormente.

Respuesta corta : reinstale el controlador.

Respuesta larga : también utilicé Dependency Walker , que identificó varios módulos de dependencia faltantes. Inmediatamente, pensé que debía haber sido una instalación de controlador fallida. No quería comprobar y restaurar cada archivo que faltaba.

El hecho de que no pude encontrar el desinstalador en Programas y características del Panel de control es otro indicador de una mala instalación. Tuve que eliminar manualmente un par de * .dll en \ system32 y claves de registro para permitir la reinstalación del controlador.

Problema solucionado.

La parte inesperada fue que no se resolvieron todos los módulos de dependencia. Sin embargo, ahora se puede hacer referencia al * .dll de interés.

icernos
fuente
1

Me he encontrado con el mismo problema, en mi caso tenía dos PC de 32 bits. Uno con .NET4.5 instalado y el otro era una PC nueva.

mi cpp dll de 32 bits (compilación en modo de lanzamiento) funcionaba bien con una PC instalada en .NET pero no con una PC nueva donde recibí el siguiente error

No se puede cargar la DLL 'PrinterSettings.dll': no ​​se pudo encontrar el módulo especificado. (Excepción de HRESULT: 0x8007007E)

finalmente,

Acabo de construir mi proyecto en la configuración del modo de depuración y esta vez mi cpp dll estaba funcionando bien.

Abu Muhammad
fuente
0

También enfrentó el mismo problema al usar un archivo dll c / c ++ no administrado en el entorno c #.

1.Comprueba la compatibilidad de dll con CPU de 32 bits o 64 bits.

2. Verifique las rutas correctas de la carpeta DLL .bin, system32 / sysWOW64 o la ruta dada.

3.Compruebe si faltan archivos PDB (base de datos de programas) .Este video le brinda una mejor comprensión de los archivos pdb.

Al ejecutar código binario C / C ++ de 32 bits en un sistema de 64 bits, esto podría surgir debido a la incompatibilidad de la plataforma. Puede cambiarlo desde Compilación> Administrador de configuración.

Yuresh Karunanayake
fuente
0

Enfrenté el mismo problema al importar C ++ Dll en .Net Framework +4, desmarqué Proyecto-> Propiedades-> Compilación-> Preferir 32 bits y se resolvió por mí.

Mamo Ghandi
fuente