Loading native dlls for P/Invoke in MSTest - c#

We have the following project setup:
A native C++ project containing some custom native code Example.Native, producing a dll with the name example_native.dll
A wrapper project, defined in Swig, which wraps Example.Native, called Example.Native.Wrapper. It wraps the example_native.dll functions using typical P/Invoke calls and the [DllImport(...)] attribute
A normal .NET (5.0) project Example.Managed, which references Example.Native.Wrapper. There are no direct references to the native project itself
An executable project Example.Runner which references Example.Managed and indirectly uses the native dlls without any issues. When running the project and inspecting the loaded modules I can see the example_native.dll is loaded
We want to write integration tests for the Example.Managed project which includes the calls to Example.Native, as the integration is relatively complex and isolated unit tests would not give us enough confidence. We use MSTest for testing
However, when we run the integration tests, we always get the exception
System.DllNotFoundException: Unable to load DLL 'example_native' or one of its dependencies: The specified module could not be found. (0x8007007E)
I already figured out the following:
During test execution, the native dlls don't get loaded. They do not appear in the Modules
list.
The file exists in the working dir. Running Assert.That(File.Exists("example_native.dll")) is true. I also check the bin directory, and it exists there as well
I found a lot of similar questions, but most of them relate to older versions of visual studio, and their solutions don't seem to work
.testsettings file which references the dlls. appears to not be supported anymore in VS2022, as it crashes when trying to edit the file. Doing so in VS2019 worked, but the tests still failed
.runsetting file with the content below, did also not work, but honestly I'm not sure here if I included it correctly. I extended the project file with <RunSettingsFilePath>...</RunSettingsFilePath>
<MSTest>
<DeploymentEnabled>False</DeploymentEnabled>
<AssemblyResolution>
<Directory path="path\to\dlls" includeSubDirectories="true"/>
</AssemblyResolution>
</MSTest>
Possible related answers: Can't load DLL while executing tests with MS-Test
Is there any way I can get these dlls to load and my tests to run?

Related

Setting up a project for release in visual studio 2013

I'm working on a C# project that is nearing release. As part of this, I have started building the project and testing it on another machine. This has revealed some odd problems. My biggest concern, though, is that my project is failing to run. I can do some basic things, but when I try to use my projects primary functionality it crashes. Using Visual Studio, I was able to determine the exception that was causing the crash.
Essentially, I'm getting a FileNotFoundException on the dll that contains most of my project's functional code. I'm not sure if I've made an error in adding the dll to my project, or if there's a problem in one of the files in the dll.
The dll was added as a reference using the Project -> Add Reerences feature of the user interface.
The dll contains three files which contain absolute file paths (these are for #import statements). Example follows.
#import "C:\Users\Me\Documents\Projects\MyProject\Delegates\bin\MyDelegate.tlb" raw_interfaces_only
My hang up is I'm not exactly sure what I'm doing wrong here. I suspect that those import statements are causing problems, but I'm not exactly sure how to fix them if they in fact are the problem. This is my first c#/c++ project so any help would be appreciated.
Adding the dll as a reference DOES NOT include the dll with your project--you are simply telling your project to use the library for your code. The dll will need to be installed on all computers that run your application, for your application to use the dll.
If the dll also uses three files (as you specified), then those files must also be included, and be installed in the expected path.
Presuming you have redistribution rights on the dll you mention, you can include the dll in your project. Be sure to set the "copy" property as "copy always" or "copy if newer" and change the reference to use the copy that ends up in you bin folder. Then you only need to be sure to include that dll and install it in the same folder as your application.

ImageMagick.NET 'Could Not Load File or Assembly'

I'm trying to get set up with ImageMagick.NET with Visual Studio 2012. I've done much research into what seems to be a common issue whereby Visual Studio is not recognizing the dependencies of ImageMagick.NET (it recognizes the .NET DLL just fine judging by the auto complete). I took steps suggested in threads such as this:
http://imagemagick.codeplex.com/discussions/66874
whereby the .NET DLL is referenced within the project, making sure I take note I chose the 16-numbered build, then downloading the 6.5.3-10 versioned dependencies from the following link:
http://image_magick.veidrodis.com/image_magick/binaries/
which installs the DLLs and places them automatically on the system path so I shouldn't theoretically have to copy the DLL's from the install directory into my project.... but this I also have done, in several different locations, including the project root, bin, the Debug and x86 directories, etc. I also made sure I was building for x86 machines, as that seems to be the only architecture supported by the DLL. Yet despite my measures, no dice! I would greatly appreciate if someone has any further insight into why this might be happening the way it is. I'm building a C# project and trying to just initialize the project within a Windows 8 grid app template.
Thanks in advance!
EDIT: I apologize in not being explicit about the error message I am receiving:
Exception: Thrown: "Could not load file or assembly 'ImageMagickNET.DLL' or one of its dependencies. The specified module could not be found."

Loading C# DLL to C++/CLI - dependencies directory

I wrote a dll c++/cli library which uses my other c# dll library. C++/cli library works fine when I've got c# dll in the same folder as application which calls it. This library will be finally loaded to many applications and a C# dll must not be copied into directory with application. It has to be in the same folder as c++/cli library, but in that cases I've got System.IO.FileNotFoundException.
My suggestion is to load c# library manually or to change path where f.ex. firefox is looking for dependencies, but I tried with LoadLibrary() and Assembly::LoadFrom() methods to force loading from right directory. Of course I added directory path with dll to system PATH.
I work on VS2010.
You don't change the default directory where an application will look for dlls.
At design time put your dll in some well know location, the one you are going to deploy to. Add a reference to it, make sure it's set to Don't copy ever, otherwise it will end up in the bin folder. You have to do this otherwise it won't compile.
When you deploy, you'll need one package to deploy common dlls, and one for each application. Careful you don't create your own version of dll hell, if appA needs an older or new version of the common dll, compared to AppB
Add an AppDomain.AssemblyResolve event to main (for windows app). At run time the event handler will get fired when you reference a type in your dll, and the assembly has not yet been loaded.
In there you load it from the well known location. That usually in config, or in a relative path.
E.g.
AllMyApps
CommonDLLS
MyFirstApp
So the path you load the required common dll from would be "..\CommonDlls\MyCommondll.dll".
NB you will want to secure the dlls in some way, otherwise a bad guy might be able to inject their version of one in to your app, which would be bad...
You can use this mechanism to get the dll from a remote server or a database blob as well.
The simplest case is only a few lines of code, just look the event up. Took me about 15 minutes to get this going in a similar scenario.
Not on this machine though, otherwise I'd have pasted in the code.

DLL Not Found after using ILMerge

After screwing my head several times over with SQLite causing havok on some machines, I stumbled across a 'Managed Only' version of the library. http://sourceforge.net/projects/sqlite-dotnet2/files/SQLite%20for%20ADO.NET%202.0/1.0.66.0/
I got excited and put this into my project folder, so now my project works on everyone's computer, regardless of architecture!
I got so excited in fact, that I decided to try using ILMerge again (since all my dependencies are now managed) instead of having to copy the DLL files as resources and write them to the output folder if it detects their absence.
I compiled the EXE with the following command:
ilmerge.exe /target:winexe /zeroPeKind /out:"Core View.exe" CoreView.exe System.Data.SQLite.dll OpenHardwareMonitorLib.dll
(The zeroPeKind flag is needed because although SQLite is managed, it isn't flagged as such and causes errors on compilation if zeroPeKind isn't present)
Problem now is that, although it starts up fine, I get the following error when trying to do any database operations when the DLL file is not present:
System.DllNotFoundException: Unable to load DLL 'System.Data.SQLite.DLL'
Can I fix this easily?
This is the only fully managed sqlite3 library I know of.
http://code.google.com/p/csharp-sqlite/

Referenced DLL Cannot Be Found When Running Application

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.

Categories