Dll Access not Working When Switching Startup Projects - c#

I am currently developing a program that uses the Ghost Script DLL, by importing it as so:
[DllImport("gsdll32.dll", EntryPoint = "gsapi_init_with_args")]
Now, when I set the project in my solution that uses this directly (located in the directory...\source\repos\uo_test_viewer\omr_scanner\omrmarkengine-master) as the startup project, everything works fine. However, when I change my startup project to a project located in ...\source\repos\uo_test_viewer\UOTestViewer, I get the following error:
The gsdll32.dll wasn't found in the default search path or is not in correct version
(doesn't expose required methods). Please download at least the version 8.64 from the original website.
The only thing that is being changed is that when I set the project that makes this work as the startup project, I am running it directly -- where as with the project that doesn't work, I am creating an object of the form that uses the Ghost Script implementation. Does anybody know what the issue is?
I believe that I have provided all the necessary information, but please let me know if anything more is required. Thank you in advance for your answers!

DllImport looks first in the current working directory, then in the search path (the $PATH) environment variable).
When you start your application in the folder which contains the Ghostscript DLL, then the Windows API call DllImport looks in the current working directory and finds the Ghostscript DLL, so it loads it.
When you start in a directory which does not contain the Ghostscript DLL, then DllImport looks in the Current Working Directory, and does not find the DLL. It then searches the search path, which presumably does not find a Ghostscript DLL, so you get an error.
You either need to be sure the current working directory has a copy of the Ghostscritp DLL, or the DLL is on the search path, or you need to supply a fully qualified path to the Ghostscript DLL in the first argument to DllImport.
In case you are considering distributing this application, please read the AGPL license to ensure that you comply with the terms for using Ghostscript.

Related

Could not load file or assembly "*.dll" , The system cannot find the file specified

Exception screenshot
I am pretty sure the C:/test/AdPlatform.Shared.dll is exist.
When I run this in Rider/VisoStudio, it works well.
When I try to run it as a system service, it does not work. There is no error and it creates null instance.
Adding custom Reference of Assemblies/DLL in any project will work only in Local Machine, not in other machine/Environments
ADDING THIRD PARTY DLLs IN ANY PROJECT FROM LOCAL PATH IS ALWAYS RISKER
Correct Way:
Registering the Custom DLL in GAC then Add the reference from SYSTEM PATH
For Web service/MVC Related Project(s) creating custom folders(lib) in the Solution itself and adding the DLL from that folder will be the best way to achieve it.
If you want a external library in your solution you need to place its file in a place the solution can access from anywhere (aka deploy location), meaning, put the file in a solution folder and set its using statements to its namespace anywhere you reference it in your project(s), so it will be sure to find the library you need.

C# Web Api/ MVC.net not loading assemblies properly

I'm new to C# and .net in general, and I need to use it to work with the SDK for a major piece of software we use.
I can add the assemblies they tell me to add in a console application and everything works fine. When I try to add them to any web application (either MVC or WebAPI), I keep getting errors saying other assemblies are missing. Eventually I just added every assembly/reference (not sure the correct term for this, pretty much just .dll files) in the sdk folder and now it is working. This definitely cannot be the correct way to do this.
Is there something I am missing that allows assemblies/references to load other assemblies/references, or is something else the cause of my issue?
UPDATE:
The exceptions are usually something like this:
Could not load file or assembly 'Server, Version=1.5.1.0, Culture=neutral, PublicKeyToken=d11ef57bba4acf91' or one of its dependencies. The system cannot find the file specified.
And it does not occur during build, only when the function is actually being called from the web application( in my case, since it's an api, when I visit the URL that returns my JSON data)
You can use a tool called "IL Disassembler" that is installed along with Visual Studio to see what other dependencies the SDK's Assembly depends on.
The install location may vary but mine is here...
"C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.6 Tools\ildasm.exe"
Drag and drop the SDK's assembly that you are using onto the tool and click the manifest field. A dialog will open with the other assemblies that you'll need to include.
If your console application works but the web application does not then the exception should specify which assembly is missing.
Compare you console output directory with the output directory of you web build. Make sure the dll that is required is being deployed to the web directory you are running.
In visual studio with your web project find the assembly under references and select it. Make sure that the property "Copy Local" is set to TRUE.

Gets FileNotFound Exception if managed c# class library dll is not in .exe folder when called form unmanaged code (c++)

I have to use the C# class library code in my native code which is written in c++. For this I added one interface written in c++ add the my C# class library project as dependency to it. This works fine till I put the C# dll in .exe folder , but I put this in libs folders (where we keep our dll's), I get file not found exception when tried to call the C# dll function.
Is there any way to keep c# dll in libs folder and make it work?
Thanks.
Yes, you need to re-add it from the libs folder and it will be fine. Or if you are naming the DLL in your code itself, then just provide the full path along with the DLL name. Then when you recompile, the .exe will contain the path you gave it in the source code and will look for the DLL there.
From the MSDN(LoadLibrary),
Remarks section::
The first directory searched is the directory containing the image
file used to create the calling process (for more information, see the
CreateProcess function). Doing this allows private dynamic-link
library (DLL) files associated with a process to be found without
adding the process's installed directory to the PATH environment
variable. If a relative path is specified, the entire relative path is
appended to every token in the DLL search path list. To load a module
from a relative path without searching any other path, use
GetFullPathName to get a nonrelative path and call LoadLibrary with
the nonrelative path. For more information on the DLL search order,
see Dynamic-Link Library Search Order.
The search path can be altered
using the SetDllDirectory function. This solution is recommended
instead of using SetCurrentDirectory or hard-coding the full path to
the DLL.
If a path is specified and there is a redirection file for
the application, the function searches for the module in the
application's directory. If the module exists in the application's
directory, LoadLibrary ignores the specified path and loads the module
from the application's directory. If the module does not exist in the
application's directory, LoadLibrary loads the module from the
specified directory. For more information, see Dynamic Link Library
Redirection.
If you call LoadLibrary with the name of an assembly
without a path specification and the assembly is listed in the system
compatible manifest, the call is automatically redirected to the
side-by-side assembly.
This is all you need to know about path search of a dll. The easy solution, enter the full path in LoadLibrary call or set your PATH environment variable to contain the alternate path of the dll.

C# reference that requires additional files

I'm having a problem with a third party C# class library:
The given .net dll requires additional files to be in the same directory than the .dll (config files etc.).
When I load the library as reference into asp.net project everything works smoothly until first call to the library. I get exceptions from the library saying that the required files are missing.
Now the question is where should I put those required files into? I've tried obj/debug/, bin/ and including the files in the project and selecting "Always copy to output directory", but none helped.
I guess it's something to do with IIS and its way of handling the reference/additional files?
Edit: It's working fine in Windows Forms application, but not in ASP.NET web application.
You can view source code of external class library with iLSpy or Reflector to find how exactly additional files are referenced.
It's can be an application execute path (so it must be IIS shadow copy directory) or GAC.
For that you need to read the documentation. The method throwing the error should be expecting the file in some other folder other than bin, debug or obj.

Unable to load dll: Module cannot be found

I am using a managed DLL that referencing an unmanaged dll.
I added the unmanaged dll under /External/foo/ directory, and i changed the "Copy To Output Directory" to always.
The problem is that the dlls are copied to the outputDir/External/foo dir and when the runtime tries to find it, it fails with this error: "Unable to load dll: Module cannot be found"
When i copy it directly to the output dir, everything works well.
How can i set the project runtime to search in the sub directories of the outut dir?
Thanks!
You don't want to do this, DLL Search Hell is something you want to avoid. Windows is pretty inflexible about where it looks for DLLs. Rightfully so, DLL Hell is nothing to mess with. The only good place for unmanaged DLLs is in the same directory as your EXE. If you don't want to store the DLLs in the project directory, so copying them is very easy, then you are going to need a post-build event that uses xcopy.exe to copy the DLL to the output directory.
The alternatives are not pretty. If this DLL is implicitly loaded then the only option is to use an installer to add the directory to the system's PATH environment variable. This is a Really Bad idea, way too easy for your program to break. If it is loaded explicitly, either with LoadLibrary or a pinvoke declaration then you have more attractive options since you can alter the search path in your Main() method before the DLL is needed. Either append the path to your local copy of the PATH environment variable by using Environment.SetEnvironmentVariable() or pinvoke SetDllDirectory(). Do beware that you have a deployment problem as well, somebody is going to have to create this subdirectory and copy the DLL there on the user's machine. All great reasons to not do this.
This is something we did in our last project. Write a batch file which copies this unmanaged dll to the output directory. Call the batch file every time the program compiles. You can control the calling of batch file also using a Config key. So it runs based on the config key value true/false. i hope this helps

Categories

Resources