I have a dll library with unmanaged C++ API code I need to use in my .NET 4.0 application. But every method I try to load my dll I get an error:
Unable to load DLL 'MyOwn.dll': The specified module could not be found. (Exception from HRESULT: 0x8007007E)
I have read and tried several solutions I have found on the internet. Nothing works..
I have tried using following methods:
[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);
When I tried following this article and when I run this example (from the downloaded code) it runs without a problem (the dll used is in the bin/debug folder)
I have copied my dll (along with all the files the it depends on into my bin folder).
I also tried this approach but got the same error:
[DllImportAttribute(MyOwnLibDllPath, EntryPoint="TMproIni")]
[return: MarshalAs(UnmanagedType.I4)]
public static extern int MyproIni(string DBname, string DBuser_pass,
string WorkDirectory, ref StringBuilder ErrorMessage);
Any suggestions?
From what I remember on Windows the search order for a dll is:
Current Directory
System folder, C:\windows\system32 or c:\windows\SysWOW64 (for 32-bit process on 64-bit box).
Reading from the Path environment variable
In addition I'd check the dependencies of the DLL, the dependency walker provided with Visual Studio can help you out here, it can also be downloaded for free: http://www.dependencywalker.com
You can use the dumpbin tool to find out the required DLL dependencies:
dumpbin /DEPENDENTS my.dll
This will tell you which DLLs your DLL needs to load. Particularly look out for MSVCR*.dll. I have seen your error code occur when the correct Visual C++ Redistributable is not installed.
You can get the "Visual C++ Redistributable Packages for Visual Studio 2013" from the Microsoft website. It installs c:\windows\system32\MSVCR120.dll
In the file name, 120 = 12.0 = Visual Studio 2013.
Be careful that you have the right Visual Studio version (10.0 = VS 10, 11 = VS 2012, 12.0 = VS 2013...) right architecture (x64 or x86) for your DLL's target platform, and also you need to be careful around debug builds. The debug build of a DLL depends on MSVCR120d.dll which is a debug version of the library, which is installed with Visual Studio but not by the Redistributable Package.
The DLL has to be in the bin folder.
In Visual Studio, I add the dll to my project NOT in References, but "Add existing file". Then set the "Copy to Output Directory" Property for the dll to "Copy if newer".
This is a 'kludge' but you could at least use it to sanity-test:
Try hard-coding the path to the DLL in your code
[DllImport(#"C:\\mycompany\\MyDLL.dll")]
Having said that; in my case running dumpbin /DEPENDENTS as suggested by #anthony-hayward, and copying over 32-bit versions of the DLLs listed there into my working directory solved this problem for me.
The message is just a bit misleading, becuase it isn't "my" dll that can't be loaded - it's the dependencies
Try to enter the full-path of the dll.
If it doesn't work, try to copy the dll into the system32 folder.
"Unable to load DLL 'xxx.dll': The specified module could not be found. (Exception from HRESULT: 0x8007007E)" means the file CAN be found BUT it's not able to load it. Try to copy the DLL file to the root folder of your application, some DLL libraries need to be available in the root folder of the application in order for it to work. Or check if there are any other depending DLL files required by it.
"Cannot find DLL 'xxx.dll': ..." means the file CANNOT be found. Try to check the path. For example, [DllImport(#"\Libraries\Folder\xxx.dll")]
Ensure that all dependencies of your own dll are present near the dll, or in System32.
Turn on the fusion logging, see this question for lots of advice on how to do that. Debugging mixed-mode apps loading problems can be a right royal pain. The fusion logging can be a big help.
Make sure you set the Build Platform Target to x86 or x64 so that it is compatible with your DLL - which might be compiled for a 32 bit platform.
There is one very funny thing (and has a technical relevance) which might waste your hours so thought of sharing it here -
I created a console application project ConsoleApplication1 and a class library project ClassLibrary1.
All the code which was making the p/invoke was present in ClassLibrary1.dll. So before debugging the application from visual studio I simply copied the C++ unmanaged assembly (myUnmanagedFunctions.dll) into the \bin\debug\ directory of ClassLibrary1 project so that it can be loaded at run-time by the CLR.
I kept getting the
Unable to load DLL
error for hours. Later on I realized that all such unmanaged assemblies which are to be loaded need to be copied into the \bin\debug directory of the start-up project ConsoleApplication1 which is usually a win form, console or web application.
So please be cautious the Current Directory in the accepted answer actually means Current Directory of main executable from where you application process is starting. Looks like an obvious thing but might not be so at times.
Lesson Learnt - Always place the unamanaged dlls in the same directory as the start-up executable to ensure that it can be found.
I had the same problem when I deployed my application to test PC. The problem was development PC had msvcp110d.dll and msvcr110d.dll but not the test PC.
I added "Visual Studio C++ 11.0 DebugCRT (x86)" merge module in InstalledSheild and it worked. Hope this will be helpful for someone else.
In my case one unmanaged dll was depending on another which was missing. In that case the error will point to the existing dll instead of the missing one which can be really confusing.
That is exactly what had happen in my case. Hope this helps someone else.
If the DLL and the .NET projects are in the same solution and you want to compile and run both every time, you can right click the properties of the .NET project, Build events, then add something like the following to Post-build event command line:
copy $(SolutionDir)Debug\MyOwn.dll .
It's basically a DOS line, and you can tweak based on where your DLL is being built to.
I think your unmanaged library needs a manifest.
Here is how to add it to your binary. and here is why.
In summary, several Redistributable library versions can be installed in your box but only one of them should satisfy your App, and it might not be the default, so you need to tell the system the version your library needs, that's why the manifest.
Setup: 32-bit Windows 7
Context: Installed a PCI-GPIB driver that I was unable to communicate through due to the aforementioned issue.
Short Answer: Reinstall the driver.
Long Answer:
I also used Dependency Walker, which identified several missing dependency modules. Immediately, I thought that it must have been a botched driver installation. I didn't want to check and restore each missing file.
The fact that I was unable to find the uninstaller under Programs and Features of the Control Panel is another indicator of bad installation. I had to manually delete a couple of *.dll in \system32 and registry keys to allow for driver re-installation.
Issue fixed.
The unexpected part was that not all dependency modules were resolved. Nevertheless, the *.dll of interest can now be referenced.
I have come across the same problem, In my case I had two 32 bit pcs.
One with .NET4.5 installed and other one was fresh PC.
my 32-bit cpp dll(Release mode build) was working fine with .NET installed PC but Not with fresh PC where I got the below error
Unable to load DLL 'PrinterSettings.dll': The specified module could not be
found. (Exception from HRESULT: 0x8007007E)
finally,
I just built my project in Debug mode configuration and this time my
cpp dll was working fine.
Also faced the same problem when using unmanaged c/c++ dll file in c# environment.
1.Checked the compatibility of dll with 32bit or 64bit CPU.
2.Checked the correct paths of DLL .bin folder, system32/sysWOW64 , or given path.
3.Checked if PDB(Programme Database) files are missing.This video gives you ans best
undestand about pdb files.
When running 32-bit C/C++ binary code in 64bit system, could arise this because of platform incompatibility. You can change it from Build>Configuration manager.
I faced the same problem when import C++ Dll in .Net Framework +4, I unchecked Project->Properties->Build->Prefer 32-bit and it solved for me.
It has nothing to do with dependencies if you checked all dependencies and you know you got them all, it has nothing to do with the file being in the wrong directory either or incorrect ARGUMENTS passed to dll, the DLL Fails to load using LoadLibrary itself.. you could check the address returned from LoadLibrary is always 0x0000000 (not loaded).
I couldn't figure this error out either it worked fine on Windows 7, but on Windows 10 it doesn't work. I fixed the problem though it had nothing to do with missing dependencies or Runtime redistributable packs.
The problem was I had to pack the DLL with upx and it started working again.
Something with the file being unpacked and compiled on old Windows XP operating system created a bad PE Header or Bad file format or something, but packing it with UPX did the trick works fine now and the DLL got 3x smaller haha.
I got this error for one C++ project in our solution, and only on our buildmaster's machine. The rest of us could build it with no problem.
In our case it was because that particular project had <WindowsTargetPlatformVersion> in the .vcxproj file set to "10.0" vs. "10.0.18362.0" as in all our other C++ projects.
Not specifying the entire SDK version number seems to have allowed MSBuild to choose the newest(?) SDK and associated build tools.
Our buildmaster likely had the remnants of a newer SDK on his machine, and MSBuild was trying to use it (and thus RC.exe was not found).
In any case, bringing up the project's property page and changing Configuration Properties > General > Windows SDK Version to "10.0.18362.0" (or whichever specific version of the SDK you have installed) for all of the project's configurations/platforms did the trick.
Related
In my C# Wpf project, I need some funtion from C++. So I make my own C++ DLL project named LibC. And the Wpf app can run normally in my computer. But on the tester's computer, the log says:
Unable to load DLL 'LibC.dll': The specified module could not be found. (Exception from HRESULT: 0x8007007E)
And I checked that the DLL file LibC.dll is there.
By checking this post: Unable to load DLL (Module could not be found HRESULT: 0x8007007E)
Anthony Hayward's answer inspires me. So I run below dumpbin command and find that my dll rely on those 4 Window's dll. And on the tester's computer, two are missing: vcruntime140d.dll and ucrtbased.dll. While on my computer, all the four dlls can be found. So I copied the missing two dlls to the tester's computer, put them together with my LibC.dll, then the app works well now.
My question is how to solve this kind of problem in a better way?
As I said, I copy the missing dll files manually to the tester's computer.
Another options is to put the two dlls into my project and release them together with my project files, including the exe file and LibC.dll.
Is it possible to statically link the two missing dll into my LibC.dll? Or any other advise?
"c:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\vc\Tools\MSVC\14.29.30133\bin\Hostx64\x64\dumpbin.exe" /DEPENDENTS libc.dll
Microsoft (R) COFF/PE Dumper Version 14.29.30143.0
Copyright (C) Microsoft Corporation. All rights reserved.
Dump of file libc.dll
File Type: DLL
Image has the following dependencies:
KERNEL32.dll
USER32.dll
VCRUNTIME140D.dll
ucrtbased.dll
Summary
1000 .00cfg
1000 .data
2000 .idata
1000 .msvcjmc
3000 .pdata
4000 .rdata
1000 .reloc
1000 .rsrc
A000 .text
10000 .textbss
Your users will need to install the visual c++ runtime. The typical way to do this would be with an installer that does this silently. As far as I know they cannot be compiled into your program, and that the license prohibit distribution of lose dlls outside the redistribution package.
Note that you may need to update this package if you update the Visual studio version used to compile your dll.
Also note that you need to deploy the release build of your application, since the debug version of the dlls is only distributed as part of visual studio.
At last, that pure .Net code does not have these kinds of problems, so if you have c++ code it might be better to just rewrite it in c#. If you want to access some third party dll it might be better to use P/Invoke directly to that dll.
I have a dll library with unmanaged C++ API code I need to use in my .NET 4.0 application. But every method I try to load my dll I get an error:
Unable to load DLL 'MyOwn.dll': The specified module could not be found. (Exception from HRESULT: 0x8007007E)
I have read and tried several solutions I have found on the internet. Nothing works..
I have tried using following methods:
[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);
When I tried following this article and when I run this example (from the downloaded code) it runs without a problem (the dll used is in the bin/debug folder)
I have copied my dll (along with all the files the it depends on into my bin folder).
I also tried this approach but got the same error:
[DllImportAttribute(MyOwnLibDllPath, EntryPoint="TMproIni")]
[return: MarshalAs(UnmanagedType.I4)]
public static extern int MyproIni(string DBname, string DBuser_pass,
string WorkDirectory, ref StringBuilder ErrorMessage);
Any suggestions?
From what I remember on Windows the search order for a dll is:
Current Directory
System folder, C:\windows\system32 or c:\windows\SysWOW64 (for 32-bit process on 64-bit box).
Reading from the Path environment variable
In addition I'd check the dependencies of the DLL, the dependency walker provided with Visual Studio can help you out here, it can also be downloaded for free: http://www.dependencywalker.com
You can use the dumpbin tool to find out the required DLL dependencies:
dumpbin /DEPENDENTS my.dll
This will tell you which DLLs your DLL needs to load. Particularly look out for MSVCR*.dll. I have seen your error code occur when the correct Visual C++ Redistributable is not installed.
You can get the "Visual C++ Redistributable Packages for Visual Studio 2013" from the Microsoft website. It installs c:\windows\system32\MSVCR120.dll
In the file name, 120 = 12.0 = Visual Studio 2013.
Be careful that you have the right Visual Studio version (10.0 = VS 10, 11 = VS 2012, 12.0 = VS 2013...) right architecture (x64 or x86) for your DLL's target platform, and also you need to be careful around debug builds. The debug build of a DLL depends on MSVCR120d.dll which is a debug version of the library, which is installed with Visual Studio but not by the Redistributable Package.
The DLL has to be in the bin folder.
In Visual Studio, I add the dll to my project NOT in References, but "Add existing file". Then set the "Copy to Output Directory" Property for the dll to "Copy if newer".
This is a 'kludge' but you could at least use it to sanity-test:
Try hard-coding the path to the DLL in your code
[DllImport(#"C:\\mycompany\\MyDLL.dll")]
Having said that; in my case running dumpbin /DEPENDENTS as suggested by #anthony-hayward, and copying over 32-bit versions of the DLLs listed there into my working directory solved this problem for me.
The message is just a bit misleading, becuase it isn't "my" dll that can't be loaded - it's the dependencies
Try to enter the full-path of the dll.
If it doesn't work, try to copy the dll into the system32 folder.
"Unable to load DLL 'xxx.dll': The specified module could not be found. (Exception from HRESULT: 0x8007007E)" means the file CAN be found BUT it's not able to load it. Try to copy the DLL file to the root folder of your application, some DLL libraries need to be available in the root folder of the application in order for it to work. Or check if there are any other depending DLL files required by it.
"Cannot find DLL 'xxx.dll': ..." means the file CANNOT be found. Try to check the path. For example, [DllImport(#"\Libraries\Folder\xxx.dll")]
Ensure that all dependencies of your own dll are present near the dll, or in System32.
Turn on the fusion logging, see this question for lots of advice on how to do that. Debugging mixed-mode apps loading problems can be a right royal pain. The fusion logging can be a big help.
Make sure you set the Build Platform Target to x86 or x64 so that it is compatible with your DLL - which might be compiled for a 32 bit platform.
There is one very funny thing (and has a technical relevance) which might waste your hours so thought of sharing it here -
I created a console application project ConsoleApplication1 and a class library project ClassLibrary1.
All the code which was making the p/invoke was present in ClassLibrary1.dll. So before debugging the application from visual studio I simply copied the C++ unmanaged assembly (myUnmanagedFunctions.dll) into the \bin\debug\ directory of ClassLibrary1 project so that it can be loaded at run-time by the CLR.
I kept getting the
Unable to load DLL
error for hours. Later on I realized that all such unmanaged assemblies which are to be loaded need to be copied into the \bin\debug directory of the start-up project ConsoleApplication1 which is usually a win form, console or web application.
So please be cautious the Current Directory in the accepted answer actually means Current Directory of main executable from where you application process is starting. Looks like an obvious thing but might not be so at times.
Lesson Learnt - Always place the unamanaged dlls in the same directory as the start-up executable to ensure that it can be found.
I had the same problem when I deployed my application to test PC. The problem was development PC had msvcp110d.dll and msvcr110d.dll but not the test PC.
I added "Visual Studio C++ 11.0 DebugCRT (x86)" merge module in InstalledSheild and it worked. Hope this will be helpful for someone else.
In my case one unmanaged dll was depending on another which was missing. In that case the error will point to the existing dll instead of the missing one which can be really confusing.
That is exactly what had happen in my case. Hope this helps someone else.
If the DLL and the .NET projects are in the same solution and you want to compile and run both every time, you can right click the properties of the .NET project, Build events, then add something like the following to Post-build event command line:
copy $(SolutionDir)Debug\MyOwn.dll .
It's basically a DOS line, and you can tweak based on where your DLL is being built to.
I think your unmanaged library needs a manifest.
Here is how to add it to your binary. and here is why.
In summary, several Redistributable library versions can be installed in your box but only one of them should satisfy your App, and it might not be the default, so you need to tell the system the version your library needs, that's why the manifest.
Setup: 32-bit Windows 7
Context: Installed a PCI-GPIB driver that I was unable to communicate through due to the aforementioned issue.
Short Answer: Reinstall the driver.
Long Answer:
I also used Dependency Walker, which identified several missing dependency modules. Immediately, I thought that it must have been a botched driver installation. I didn't want to check and restore each missing file.
The fact that I was unable to find the uninstaller under Programs and Features of the Control Panel is another indicator of bad installation. I had to manually delete a couple of *.dll in \system32 and registry keys to allow for driver re-installation.
Issue fixed.
The unexpected part was that not all dependency modules were resolved. Nevertheless, the *.dll of interest can now be referenced.
I have come across the same problem, In my case I had two 32 bit pcs.
One with .NET4.5 installed and other one was fresh PC.
my 32-bit cpp dll(Release mode build) was working fine with .NET installed PC but Not with fresh PC where I got the below error
Unable to load DLL 'PrinterSettings.dll': The specified module could not be
found. (Exception from HRESULT: 0x8007007E)
finally,
I just built my project in Debug mode configuration and this time my
cpp dll was working fine.
Also faced the same problem when using unmanaged c/c++ dll file in c# environment.
1.Checked the compatibility of dll with 32bit or 64bit CPU.
2.Checked the correct paths of DLL .bin folder, system32/sysWOW64 , or given path.
3.Checked if PDB(Programme Database) files are missing.This video gives you ans best
undestand about pdb files.
When running 32-bit C/C++ binary code in 64bit system, could arise this because of platform incompatibility. You can change it from Build>Configuration manager.
I faced the same problem when import C++ Dll in .Net Framework +4, I unchecked Project->Properties->Build->Prefer 32-bit and it solved for me.
It has nothing to do with dependencies if you checked all dependencies and you know you got them all, it has nothing to do with the file being in the wrong directory either or incorrect ARGUMENTS passed to dll, the DLL Fails to load using LoadLibrary itself.. you could check the address returned from LoadLibrary is always 0x0000000 (not loaded).
I couldn't figure this error out either it worked fine on Windows 7, but on Windows 10 it doesn't work. I fixed the problem though it had nothing to do with missing dependencies or Runtime redistributable packs.
The problem was I had to pack the DLL with upx and it started working again.
Something with the file being unpacked and compiled on old Windows XP operating system created a bad PE Header or Bad file format or something, but packing it with UPX did the trick works fine now and the DLL got 3x smaller haha.
I got this error for one C++ project in our solution, and only on our buildmaster's machine. The rest of us could build it with no problem.
In our case it was because that particular project had <WindowsTargetPlatformVersion> in the .vcxproj file set to "10.0" vs. "10.0.18362.0" as in all our other C++ projects.
Not specifying the entire SDK version number seems to have allowed MSBuild to choose the newest(?) SDK and associated build tools.
Our buildmaster likely had the remnants of a newer SDK on his machine, and MSBuild was trying to use it (and thus RC.exe was not found).
In any case, bringing up the project's property page and changing Configuration Properties > General > Windows SDK Version to "10.0.18362.0" (or whichever specific version of the SDK you have installed) for all of the project's configurations/platforms did the trick.
I have a code sample that's supposed to detect my canon 550d digital camera so I can control the camera from the pc.
I just downloaded the source files from here:
http://www.codeproject.com/Articles/17344/A-wrapper-for-the-canon-CDSDK-and-PRSDK-for-remote?fid=379739&df=90&mpp=25&noise=3&prof=False&sort=Position&view=Quick&spc=Relaxed&fr=1#xx0xx
I created a new project in Visual Studio 2012 Pro; my pc is running Windows 8 64bit.
I added all the .cs files and also copied all the dll files I downloaded from the Canon website after registering.
The first time I ran the program and clicked on the connect button, I got an exception that a dll is missing. Since there is no way to add the dlls as referenced, I copied them to the Debug directory.
The missing dll was PRSDK.dll, so I found and downloaded the dll, and copied it.
Now when I click on the connect button, I get a different exception:
BadImageFormatException: An attempt was made to load a program with an incorrect format. (Exception from HRESULT: 0x8007000B)
The exception is in the file Camera.cs, on the line:
err = prAPI.PR_StartSDK();
I googled for this exception and found that some people have changed the project platform and target to x86, so I tried it - I tried changing it to x86, x64, AnyCpu, everything, but it didn't help.
Maybe the PRSDK.dll file is old and not useable in Windows 8?
This is a link to my project/solution in my SkyDrive, if someone can please download it and try to run it on his machine and maybe find a solution?
https://skydrive.live.com/redir?resid=EB1C71C44C3976D5!201&authkey=!AErpIgyllPAgH9w
The project called: Canon_Camera_Control
OK, I downloaded your project and found the problem.
Your DLL files are wrong!
They are not even DLL actually, they are html files with the .dll extension. Apparently you tried to download them from some webpage but didn't succeed.
Try redownloading it or obtain the SDK from official (Canon) sources.
You must have missed something. The error is definitely the one that states that the platform of your project and the one of the external dll don't match.
Maybe you changed the "Active solution platform" but not the "Project platform".
One thing that tripped me up regarding exactly this, not too long ago: check to make sure (Build->Configuration Manager) that in your solution, when you change the solution's platform to x86, the platform of your actual project in that dialog is actually set to x86. Sometimes VS is dumb, and leaves it as Any CPU (great if all your code and all your third-party dlls are managed, not so great if you're calling, for instance, a wrapper to an unmanaged camera dll.)
It's possible something totally unrelated is going on, but every time I've seen that error it's because you're running as x86/x64 and loading an unmanaged dll that's of the other platform type.
One reason is that you might be trying to load a 32-bit assembly into a 64-bit application. This can happen when you have the Any CPU platform selected.
On my blog I outline this issue more with screenshots on how you can change it
but basically you can set your project it always compile in 32 bit mode.
I have a weird situation with some code that I inherited at work. Their application is a multi-project solution, with several of the solutions being (code) pieces of the MS Enterprise Library (not sure which version).
They also have an existing C++ (unmanaged) application which has a bunch of DLLs. One of these DLLs is built in a separate solution, both in 64-bit and 32-bit flavours.
The main application has a reference to this DLL, and calls a couple of static functions (I can see intellisense, even). I can compile and build the main application EXEs, but when I run it, I get an exception that this DLL from the unmanaged code (lets call it CPlusPlusCode.dll cannot be found:
FileNotFound Exception was unhandled: Could not load file or assembly 'CPlusPlusCode.dll' or one of its dependencies. The specified module could not be found.
I'm quite stumped, because I can compile the code, see intellisense for the imported classes, and dig into the DLL in the object browser. I even made sure there's a copy in the \bin\Debug folder (although I don't see why that would make a difference). This is for a Windows Forms application.
Also, if it matters, I had some build issues related to x86 vs. x64 for different projects; I think (hope?) that this is not related to that, but I solved that by using the Configuration Manager to build everything as x64.
Check the GAC, and if necessary you might need to add it or register the DLL there.
I had this problem with a project, it all works ok from Visual Studio and most of my times running the project locally on my machine. But because of the unmanaged code I needed specifically allow the project to be executed with correct permission levels.
So have a look in the manifest file, that enough permissions etc exist.
EDIT (the whole question, it was too unclear)
I want to use OpenSSL.NET
The OpenSSL.NET install instructions page: INSTALL
Make sure you have libeay32.dll and ssleay32.dll in the current working
directory of your application or in your PATH. DONE
In your .NET project, add a reference to the ManagedOpenSsl.dll assembly. DONE
I have put libeay32.dll and ssleay32.dll in both my bin/Debug and bin/Release directories. I have also put them in system32.
Here is my FULL code:
using System;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
try
{
OpenSSL.Crypto.RSA rsa = new OpenSSL.Crypto.RSA();
}
catch (Exception e)
{
Console.WriteLine(e.InnerException.Message);
}
Console.Read();
}
}
}
I get the following error:
Unable to load DLL 'libeay32' http://localhostr.com/files/a719c5/Error.gif
(Unable to load DLL 'libeay32')
Here is the Process Monitor log (upon request):
alt text http://localhostr.com/files/726a46/ProcMon.gif
What am I doing wrong? Why isn't the DLL found?
Try the latest version of OpenSSL.NET (0.4.1) which should now include prebuilt libeay32.dll and ssleay32.dll binaries that link to the CRT statically. Alternatively, you can build these libraries yourself or use an 'official' build from openssl.org.
Without looking at your code exactly, I get that error when I:
do not have the dlls in the path of the executable (not where your sln resides, but where the .exe is made, typically in bin/debug or bin/x86/debug or whatever).
do not have the proper signature of the calling function (ie, I left out an integer parameter, the return types don't match, etc).
am not marshalling the types properly (ie, BOOL is marshalled as a bool, while bool is marshalled as a unsigned single byte integer, etc)-- while this last one may not cause the exception, it can cause decidedly funky behavior.
am on a 64 bit platform and am calling a 32 bit dll. The pointer sizes will be all different, and the dll will probably just crash and cause that exception.
EDIT: When all else fails, try dependency walker, because it sounds like your dlls are calling other dlls that aren't in your path or in the directory of the executable.
For anyone else out there still experiencing this issue (and have verified that the necessary prerequisites exist in their correct locations:
Check the OpenSSL.NET installation documentation and ensure its prerequisites are installed. In my case, a user was missing the Microsoft Visual C++ 2010 Redistributable Package (x86) dependency which is called out in the OpenSSL.NET documentation.
Your problem is related with this question:
DllNotFoundException, but DLL is there
Verify if all depencencies are in same folder of your application or are registred.
Try using probing. You need to create an XML config file named as the application's executable complete name (or named as the assembly that requieres your non-managed dll) with a .config extension. E.g. if your applications is name myapp.exe, the config file will be named myapp.exe.config
The config file must be located in the same directory as the executable / assembly .
The config file is a simple xml file:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<runtime>
<assemblyuBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<probing privatePath="PATH" />
</assemblyuBinding>
</runtime>
</configuration>
Now the application will search in PATH when loading the assemblies. PATH is relative to the config /assembly file.
Not sure if it will work for non-managed dlls, but is worth the try.
The .NET way of doing this is to install your assembly in the global assembly cache.
Each computer where the common
language runtime is installed has a
machine-wide code cache called the
global assembly cache. The global
assembly cache stores assemblies
specifically designated to be shared
by several applications on the
computer.
As a last resort, if nothing else works:
It may be useful to know where the application (.net or not) is looking for the DLLs. Just use Process Monitor and filter for the file name of the DLL. Then copy it to a location where the application is looking for it.
You're probably missing the VC++ redistributables. I'm assuming OpenSSL.NET is x86 only, so you can grab the VS2008 version x86 redistributable if they're release builds.
Otherwise, if they're debug builds (you'll see Microsoft.VC90.DebugCRT in EventViewer or the sxstrace logs) then you'll need to either:
Rebuild them as release
Install or copy the debug redistributables from another machine
Install Visual C++ into Visual Studio (or, probably, Visual C++ Express)
I found a solution.
Unfortunately the VS2008 C++ Redistributable package didn't work - I had to install the SP1 version AND VC++2008. The author said in a comment on its website that it was a mistake on its side, and not mine. He is currently recompiling the DLLs to be statically linked. Thank you to all of those who helped me :)
Try changing the Platform target for your project to x86 instead of "any cpu".
In my case, when we develop a web site with open ssl on x64 win 2008 platforms, we must check with application pool : allow 32 applications : true
Create New Folder Named x86 in your application path and then put libeay32.dll,ssleay32.dll in x86 folder.