System.DllNotFoundException in .NET DLL - c#

I took a program written in C/C++ and modified it's main function to accept some arguments as input and return a variable as output and created a Win32 DLL out of it. I then created a .NET DLL which uses InterOp to access the first DLL. Now when I load the .NET DLL in my C# app I get a System.DllNotFoundException from the DLL which is really baffling me as there were never memory issues with the program and both Win32/.NET dlls are located in the same directory (apart from modifying the main function, the code has not really changed).
The solution was provided in this thread, which was my original question some time ago. I'm pretty sure that answer is correct but I'm just missing something.
You can download my VS solution Here. The solution contains three projects: the Win32 DLL, the .NET DLL, and a winform app that references the .NET DLL (but when trying to test gives the DLL exception). Any help or debugging guidance would be greatly appreciated.
UPDATE: I have tried all the tips/suggestions below but I still get the exact same error. If it makes things easier, my VS solution is available to download in the hyperlink above.

Make sure you have placed the win32 dll on /windows/system32 folder(if only the dll name is passed to DllImport)
Alternatively you can also pass the full path of the dll to the DllImport Attribute.
Use a tool such as Dependency Walker to make sure you are not missing out on any dependent assembly.

Related

Visual Studio 2012 C# - Importing a DLL

I am actually trying to use a DLL on a C# project. The problem is, whenever I try to import it in my project by adding it as a reference, I get this error message :
A reference to "C:\FilePath\LnkEMP.dll" could not be added.
Check that the file is an assembly or a valid COM component
The library is "LnkEMP.dll", used for a program called Expert/M Plus. I need this library to interract with this program.
I think that this DLL is made in C++, which could be one of the reason that my C# project can't load it.
I tried to make a C++ Library and importing it, but this time I had another error message :
A reference to "C:\FilePath\LnkEMP.dll" could not be added,
because it is not an assembly .NET, or not a registered ActiveX control
Do you have any idea of what should I do to get it work ?
You can fall back on dynamic loading of dll using Win32 api calls. There should be lots of examples of dynamical loading/calling of external dll. Hopefully your dll comes with doc on how to use it.

Find missing/broken native DLL

I am programming an application in Python which has to use some DLLs originally created from C# code. Generally the usage of such DLLs is working (proven with multiple DLLs, all from the same source). For deployment on other people computers I'm using Py2Exe which also works as intended.
But now I want to use another DLL and have the following problems. If I start the programm and make a call to a function within the DLL, it throws an error saying:
.Net Dll broken because of possibly missing native Dlls.
Now comes the strange part. If I compile the python program into an executable the message does not show up and everything works as intended.
I already tried to identify missing DLLs by comparing the DLL assembly with the ProcessExplorer but they look totally the same. Next thing was to try to set path variables to all Dlls which I am calling directly but this was no solution too.
Other informations which could be interesting are IDE and OS: I'm using Eclipse Indigo with PyDev 2.5 plugin on a Windows 7 machine.
So are there any things I could have overseen or settings which I could try to make it work?
Any suggestions are appreciated.

How do I stop my class library generating an .EXE file and causing a TypeLoadException Exception?

I've got a really strange error occurring in my solution one of my projects which is a class library is causing a project it is referenced in to throw a TypeLoadException. I've looked through various answers on SO and the closest to my issue is;
TypeLoadException was unhandled in C# [closed]
This answer led me to question if this was my issue, doing some digging in the debug folders I found that my project that was referencing my class library is generating a DLL and EXE with the same name, could this be my problem?
If so how do I fix this?, I have other class libraries in my solution that are also referenced in this project they are not generating both DLL and EXE files.
I don't believe it but I've actually found the cause via a colleague, hopefully this will help others who encounter this (nice one Adam).
The reason was my project referencing my class library had the same assembly name, I had been doing some re-jigging of my namespaces and hadn't noticed that my main project had the same name, this meant that when my code was built the compiler created a EXE for my main project and a DLL for my class library this in turn forced the TypeLoadException because the compiler had already loaded the EXE with the same name.
My code is now working. Thanks to all who took the time to post.
my class library is generating a DLL and EXE with the same name
Yes, that causes this problem. You can easily see it by running Fuslogvw.exe and logging all bindings. It is a somewhat odd quirk of Fusion, but when it looks for an assembly then it only looks at the filename and ignores the extension. It will accept both a .dll and a .exe as an acceptable match for the assembly it is looking for. Which is otherwise somewhat logical, there is no true difference between DLLs and EXEs when they contain managed code. Referencing an EXE is for example entirely supported.
There's no way to force the loader to do this differently. The workaround should otherwise be simple, just be sure to generate a distinct assembly names.
Under Project -> (YourProjectName) Properties -> Application, make sure that "Output Type" is set to "Class Library".

Calling C# from ColdFusion

I've written a .dll in C# to change the permissions on a folder. I also wrote an .exe to test the .dll and it successfully changes the permissions. Now I'm trying to call the .dll from ColdFusion, but I'm getting an error about System/Security/IPermission not being found.
I'm assuming this is an interface in C# that ColdFusion can't find in any of the available assemblies on my system. I've added the System.Security assembly to my References in the C# project. Is there something else I need to do to make sure ColdFusion can find the interface?
Here's how I'm using the .dll:
<cfobject type="dotnet" name="permObj" assembly="#pathToDLLs#CoursePortal.dll" class="CoursePortal.Permissions">
<cfset permObj.revokePermissions(dir, username)>
I never could get it to work. I switched the DLL to an EXE and used <cfexecute> to call it. It's working fine now. The .NET code is called so infrequently it doesn't make much difference that it's a separate app.

C# to C++/CLI to C DLL System.IO.FileNotFoundException

I'm getting System.IO.FileNotFoundException: The specified module could not be found when running C# code that calls a C++/CLI assembly which in turn calls a pure C DLL. It happens as soon as an object is instantiated that calls the pure C DLL functions.
BackingStore is pure C.
CPPDemoViewModel is C++/CLI calling BackingStore it has a reference to BackingStore.
I tried the simplest possible case - add a new C# unit test project that just tries to create an object defined in CPPDemoViewModel . I added a reference from the C# project to CPPDemoViewModel .
A C++/CLI test project works fine with just the added ref to CPPDemoViewModel so it's something about going between the languages.
I'm using Visual Studio 2008 SP1 with .Net 3.5 SP1. I'm building on Vista x64 but have been careful to make sure my Platform target is set to x86.
This feels like something stupid and obvious I'm missing but it would be even more stupid of me to waste time trying to solve it in private so I'm out here embarrassing myself!
This is a test for a project porting a huge amount of legacy C code which I'm keeping in a DLL with a ViewModel implemented in C++/CLI.
edit
After checking directories, I can confirm that the BackingStore.dll has not been copied.
I have the standard unique project folders created with a typical multi-project solution.
WPFViewModelInCPP
BackingStore
CPPViewModel
CPPViewModelTestInCS
bin
Debug
Debug
The higher-level Debug appears to be a common folder used by the C and C++/CLI projects, to my surprise.
WPFViewModelInCPP\Debug contains BackingStore.dll, CPPDemoViewModel.dll, CPPViewModelTest.dll and their associated .ilk and .pdb files
WPFViewModelInCPP\CPPViewModelTestInCS\bin\Debug contains CPPDemoViewModel and CPPViewModelTestInCS .dll and .pdb files but not BackingStore. However, manually copying BackingStore into that directory did not fix the error.
CPPDemoViewModel has the property Copy Local set which I assume is responsible for copying its DLL when if is referenced. I can't add a reference from a C# project to a pure C DLL - it just says A Reference to Backing Store could not be added.
I'm not sure if I have just one problem or two.
I can use an old-fashioned copying build step to copy the BackingStore.dll into any given C# project's directories, although I'd hoped the new .net model didn't require that.
DependencyWalker is telling me that the missing file is GPSVC.dll which has been suggested indicates security setting issues. I suspect this is a red herring.
edit2
With a manual copy of BackingStore.dll to be adjacent to the executable, the GUI now works fine. The C# Test Project still has problems which I suspect is due to the runtime environment of a test project but I can live without that for now.
Are the C and C++ DLLs in the same directory as the C# assembly that's executing?
You may have to change your project output settings so that the C# assembly and the other DLLs all end up in the same folder.
I've often used the Dependency Walker in cases like this; it's a sanity check that shows that all the dependencies can actually be found.
Once your app is running, you may also want to try out Process Monitor on the code you are running, to see which DLLs are being referenced, and where they are located.
The answer for the GUI, other than changing output settings, was the addition of a Pre-Build Step
copy $(ProjectDir)..\Debug\BackingStore.* $(TargetDir)
The answer for the Test projects was to add the missing DLL to the Deployment tab of the testrunconfig. You can either do so by directly editing the default LocalTestRun.testrunconfig (appears in Solution under Solution Items) or right-click the Solution and Add a new test run config, which will then appear under the main Test menu.
Thanks for the answers on this SO question on test configurations for leading me to the answer.
The reason why this happens is because you either are loading DLLMAIN from managed code, before the CRT has an opportunity to be initialized. You may not have any managed code, be executed DIRECTLY or INDERECTLY from an effect of DllMain notifications. (See: Expert C++/CLI: .Net for Visual C++ Programmers, chapter 11++).
Or you have no native entrypoint defined wahtsoever, yet you have linked to MSVCRT. The CLR is automatically initialized for you with /clr, this detail causes a lot of confusion and must be taken into account. A mixed mode DLL actually delay loads the CLR through the use of hot-patching all of the managed entry point vtables in your classes.
A number of class initialization issues surround this topic, loader lock and delay loading CLR are a bit trickey sometimes. Try to declare global's static and do not use #pragma managed/unmanaged, isolate your code with /clr per-file.
If you can not isolate your code from the managed code, and are having trouble, (after taking some of these steps), you can also look towards hosting the CLR yourself and perhaps going through the effort of creating a domain manager, that would ensure your fully "in-the-loop" of runtime events and bootstrapping.
This is exactally why, it has nothting todo with your search path, or initialization. Unfortunately the Fusion log viewer does not help that much (which is the usual place to look for .NET CLR assembly binding issues not dependency walker).
Linking statically has nothing todo with this either. You can NOT statically link a C++/CLI application which is mixed mode.
Place your DLLMAIN function into a file by itself.
Ensure that this file does NOT have /CLR set in the build options (file build options)
Make sure your linking with /MD or /MDd, and all your dependencies which you LINK use the exact same CRT.
Evaluate your linker's settings for /DEFAULTLIB and /INCLUDE to identify any possiable reference issues, you can declare a prototype in your code and use /INCLUDE to override default library link resolution.
Good luck, also check that book it's very good.
Make sure the target system has the correct MS Visual C runtime, and that you are not accidentally building the C dll with a debug runtime.
This is an interesting dilemma. I've never heard of a problem loading native .DLLs from C++/CLI after a call into it from C# before. I can only assume the problem is as #Daniel L suggested, and that your .DLL simply isn't in a path the assembly loader can find.
If Daniel's suggestion doesn't work out, I suggest you try statically linking the native C code to the C++/CLI program, if you can. That would certainly solve the problem, as the .DLL would then be entirely absorbed into the C++/CLI .DLL.
Had the same problem switching to 64-bit Vista. Our application was calling Win32 DLLs which was confusing the target build for the application. To resolve it we did the following:
Go to project properties;
Select Build tab;
Change 'Platform target:' option to x86;
Rebuild the application.
When I re-ran the application it worked.

Categories