Add reference of a .NET library residing in Windows System32 folder - c#

I am using a .NET dll file for image operations and have added it in my C# application using "Add reference" in solution explorer and use its classes. There are many applications use that dll so I do not want to place the dll file in an application specific folder like:
C:\Program Files\<Application Name>\ or
C:\Program Files (x86)\<Application Name>\ or
C:\ProgramData\<Application Name>\ or
C:\Users\<Username>\AppData\
And would like to place the dll file in a common folder like C:\Windows\ or C:\Windows\System32 folder or any other folder that is commonly accessible by all applications in Windows.
It works fine when I put the the dll file in the same folder of the calling exe, but when I place it in C:\Windows\System32 directory, the C# code of my application is not able to locate the dll and gives error:
Unable to load DLL: The specified module could not be found.
(Exception from HRESULT: 0x8007007E)
How do I instruct my code to look for the dll in the system32 directory or in any other common directory?
What other common folder can I use for shared dll and libraries?

This is what the Global Assembly Cache is designed for. As listed in the MS documentation here.
Each computer where the common language run-time 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.
But there are pitfalls to using it so be aware of MS's own advice:
You should share assemblies by installing them into the global
assembly cache only when you need to. As a general guideline, keep
assembly dependencies private, and locate assemblies in the
application directory unless sharing an assembly is explicitly
required.

Related

.net Runtime doesn't probe plugin folder

We have a .net plugin for an application that does not load a dependent library from the plugin folder.
Scenario:
Application (Revit.exe in program files) -> Loads plugin from c:\programdata\revit\plugindir\ourplugindir\<plugin.dll+dependencies>
On most machines, the load works fine. For the context of the issue, the dll dependencies are as follows
Revit.exe loads plugin.dll (revit.exe is in programfiles, plugins are in a separate predefined directory under programdata)
plugin.dll loads IdentityModel.dll (in ourplugindir directory)
IdentityModel.dll loads System.Text.Encodings.Web.DLL (in ourplugindir)
Successful probing looks like this:
IdentityModel requires System.Text.Encodings.Web.DLL
Initiate probing
Check GAC (fail)
Check root folder where Revit.exe is present (fail)
Check private sub folders where Revit.ext is present (fail)
Check ourplugindir (success)
On the machine where the plugin load fails, for some reason it does not probe ourplugindir and is hence unable to find System.Text.Encodings.Web.DLL.
The plugin dll is built using .net 4.7. The dependency is an indirect dependency.
From MSDN: https://learn.microsoft.com/en-us/dotnet/framework/deployment/how-the-runtime-locates-assemblies
Assembly location can also be determined using the current binding
context. This most often occurs when the Assembly.LoadFrom method is
used and in COM interop scenarios. If an assembly uses the LoadFrom
method to reference another assembly, the calling assembly's location
is considered to be a hint about where to find the referenced
assembly.
Since the plugins are dynamically loaded by Revit.exe, I can only assume that the application uses Assembly.LoadFrom or something similar to load the plugins.
So the question is, why does the runtime correctly probe and find the dependent dll in the plugin folder on some machines while it doesn't probe the same folder on other machines?
Have you tried using an assembly resolver?

Using assembly located in parent directory of executable file

In my simple console application I'm using dll assembly with useful functionality, and there are no issues when that files contains in the same directory. But how to reference to dll assembly, which is located in the parent directory of the executable file?
It does not work because the OS does not know where the dll is.
You can add the path of the dll to your environmental variables and it will work or add the dll to a path that's already in your environmental variables.

Dependencies referenced by xaml are not loaded from project folder but from executable folder

I have the following simple folder structure:
Root
Root\Executable.exe
Root\Subfolder
Root\Subfolder\Control.dll
Root\Subfolder\ControlDependency.dll
The subfolder has a control based on a 3rd party library. I expected the control to load its dependencies from its own folder but instead it is looking for dependencies in the executable folder.
Is this normal and why it is happening?
When you build the project, all the referenced assemblies will be copied in the output folder and then referenced.
The .NET CLR follows these steps to assembly resolving:
Examine the Configuration Files
Check for Previously Referenced Assemblies
Check the Global Assembly Cache
Locate the Assembly through Codebases or Probing
If you need to load an assembly at runtime which can be located in any folder (not only the bin folder of the application) you can use one of these three methods:
Install the assembly into the Global Assembly Cache (GAC)
Use an application configuration (.config) file with the
tag.
Use the AssemblyResolve event
Please, follow this links to learn more:
http://msdn.microsoft.com/en-us/library/yx7xezcf.aspx
http://support.microsoft.com/kb/837908/it

DLL reference location

Okay, I asked this question the other day, and it was closed due to my vagueness. I'll try to be more specific. In a project, say C# (using Visual Studio), I add a reference to a dll (right-click References->Add Reference), and the location of said dll is in C:\Blah\Foo. Now, if I move the exe that is built over to another machine, will the location of the dll need to be with the exe, or will it need to be in C:\Blah\Foo? Thank you.
When you add a reference in the way you've described it is copied to the output folder (same as the exe file). Look in the properties of the reference (F4) and you will see an option called "Copy Local", if this is set to true then the DLL will be copied to the same output folder as the EXE file.
So when you deploy your application to another machine you will need to copy the exe and all it's referenced DLLs to the deployment location. Windows will search for DLLs in a number of locations, the first of which is the same folder as the EXE file.
Typically, you'll just put the assemblies in the same folder as the application, which causes it to be in the default probing path, and get found (for most applications), but there are many other options depending on the type of application. When you define your reference, there is the option to "Copy Local" - which causes the assembly to be copied to the application's output folder. If you leave this set to True, the assembly (DLL) will be with the .exe, and typically "just work."
The full process the runtime uses is covered on MSDN in How the Runtime Locates Assemblies. In particular, the topic titled Locating the Assembly through Codebases or Probing covers how the assemblies are located in detail, which depends on a lot of factors.
The DLL should be with exe file. Have a look on this link to see where .NET serach for DLL In what order are locations searched to load referenced DLLs?
The dll could either be installed in the GAC or be present with the EXE in the same directory.
EDIT: The above mentioned are only just a couple of locations to resolve references.
When you add reference, you add path on your csproj on this assembly, dont you must just ensure that you can reference this dll.
When you deploy, it's another question, because your dll is copied on your Bin directory.
If you deploy you check your path of assembly in your csproj, and ensure that you deploy your assembly
Nota : check CopyLocal Property of your refrence
2 Other solution :
You can use GAC Global Assembly Cache in order to share your assemblies
Tools : Gacutil.exe in order to set assembly

csc.exe reference external .dll file

I am trying to make a simple c# program using Growl C# API.
I tried to compile my program in two different ways:
1) I kept my .dll file in the same directory as my .cs file. Than I ran
csc /r:Growl.Connector.dll,Growl.CoreLibrary.dll /out:test.exe *.cs
It compiled fine and also ran fine.
2) Now I have created a directory inside my current working directory named growl and kept all my .dll references there.
Now when I try to compile it using the below command
csc /r:"D:\Modified\Growl_NET_Connector_SDK\libraries\growl\Growl.Connector.dll","D:
\Modified\Growl_NET_Connector_SDK\libraries\growl\Growl.CoreLibrary.dll" /out:test.exe *.cs
It compiled fine but when I tried to run it the below mentioned exception occurred.
Unhandled Exception: System.IO.FileNotFoundException: Could not load file or assembly 'Growl.Connector, Version=2.0.0.0, Culture=n
eutral, PublicKeyToken=980c2339411be384' or one of its dependencies. The system cannot find the file specified.
at GrowlNotification.Program.Main(String[] args)
So, my question is what is the correct way to reference .dll file in csc when files are in an external folder.
Here is the directory structure for 2nd case.
So, my question is what is the correct way to reference .dll file in csc when files are in an external folder.
You're already referencing them at build time. You just need to make them available at execution time too, but copying them into the same directory as the executable, when you want to run it.
You could also investigate using the Global Assembly Cache if these are signed assemblies, but personally I'd stick with just keeping the executable with the libraries on which it depends.
You can add these using the /lib and /reference command-line switches while compiling.
http://msdn.microsoft.com/en-us/library/s5bac5fx.aspx
But (Quote from the article)
An alternative to using /lib is to copy into the working directory any
required assemblies; this will allow you to simply pass the assembly
name to /reference. You can then delete the assemblies from the
working directory. Since the path to the dependent assembly is not
specified in the assembly manifest, the application can be started on
the target computer and will find and use the assembly in the global
assembly cache.
Because the compiler can reference the assembly does not imply the
common language runtime will be able to find and load the assembly at
runtime. See How the Runtime Locates Assemblies for details on how the
runtime searches for referenced assemblies.
so Jon Skeet's answer is better. (I'm just adding this to provide more info than I could in a comment, not as an answer. Jon's answer is the best IMO)
You can create symlinks to the assemblies in your libraries folder so you would only need to keep them updated in one location.

Categories