When compiling a C# project which has external references, the referenced dlls are being copied to the project's output path (next to the exe).
When running the application, it expects to find the dlls next to the exe.
I'm looking for a way to spread my dll files into different directories Dlls for starters). And have the exe look for the dll files in those directories.
Example:
Let's say we have an application called "App" located under C:\App\App.exe, and also it uses a dll file called "App.dll" which is currently also located under C:\App.
I wish to create a new directory called C:\App\Dlls and move the App.dll file to there, while making sure that the App.exe file will know to look for the dll in the new location.
I've searched the internet and found the probing solution. Here's my code (edited "App.config" file):
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.1" />
</startup>
<runtime>
<assemblyBinding xmlns="urn:schemas=microsoft-com:asm.v1">
<probing privatePath="Dlls" />
</assemblyBinding>
</runtime>
</configuration>
I compiled my application, created the Dlls directory and moved all the dll files to that directory, but the application crashes.
What am I missing?
Found the solution, the file App.exe.config was missing from my base directory. That's why it didn't work. Now everything works smoothly.
Related
I am working on a feasibility task, where it is required to keep a C# - WPF application in a folder and to keep its dependency dlls in a separate folder. Is it possible to do dynamic loading ?
When I investigated I found that .NET assemblies should be placed in a common directory/sub directories due to security reasons, otherwise it wont work. My requirement is to separate them in a different drive-folder.
Can you suggest a solution for this?
Yes it is possible according https://learn.microsoft.com/en-us/dotnet/framework/configure-apps/file-schema/runtime/probing-element?redirectedfrom=MSDN. You will have to update your configuration file (app.config which gets copied to your.exe.config) with something like this:
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<probing privatePath="bin;bin2\subbin;bin3"/>
</assemblyBinding>
</runtime>
</configuration>
I'm using Visual Studio 2019 Community Edition. After I added the reference under subdir with copy local set to true, it works fine, then I modified the app.config to
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<probing privatePath="Mylib\"/>
</assemblyBinding>
</runtime>
</configuration>
thinking this may not require copy to local anymore, then I got
Unhandled exception. System.IO.FileNotFoundException: Could not load file or assembly 'ClassLibrary1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'.
Isn`t this the proper way to add subdir reference? (By the way, there is only *.dll.config but not *exe.config generated when I added item 'App.config' )
I finally found out that the problem here is the project type part, it seems that .net core does not support these traits, so I changed my project to console(.netframework) then the modifying app.config route works.
I've recently finished converting a WPF project to the new csproj format which is much leaner.
However I have one missing piece left, adding a probing path for the assemblies, something that used to exist in the old app.config file. With this missing my application just doesn't find the required dlls.
The way I have this set up is with a Post-build event that clears and moves items to a bin folder:
SET folder=bin
rmdir "$(TargetDir)%folder%" /s /q
mkdir "$(TargetDir)%folder%"
move "$(TargetDir)*.dll" "$(TargetDir)%folder%\"
I've tried adding some entries to the .csproj file but to no avail. I believe this is more for compiling the application:
<PropertyGroup>
<ReferencePath>bin</ReferencePath>
</PropertyGroup>
<PropertyGroup>
<AssemblySearchPaths>
$(AssemblySearchPaths);
$(ReferencePath);
</AssemblySearchPaths>
</PropertyGroup>
I guess my main question, should I still have an app.config, or is there a better .csproj approach available?
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2"/>
</startup>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<probing privatePath="bin"/>
</assemblyBinding>
</runtime>
</configuration>
My application will work if I include it, but I'd like to know if I can simplify this, or do this in a better way in general.
I am trying to load dll's via the <probing> element. I have a folder structure that consists of several plugin folders inside of plugins. So I am looking for a way to recursively go through all these plugins folders to find the dll's.
This is my folder structure:
MyApplication
myapp.exe
plugins
fooplugin
foo.dll
barplugin
bar.dll
This is what my App.config looks like, but it doesn't seem to catch the plugins\* part.
<?xml version="1.0" encoding="utf-8">
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<probing privatePath="MyApplication;plugins;plugins\*;"/>
</assemblyBinding>
</runtime>
</configuration>
If I would make it like: <probing privatePath="MyApplication;plugins;plugins\fooplugin;"> it will find foo.dll. But I am not certain which plugins will be present.
It's not possible to use a wildcard search when using the probing element. Instead you need to copy your DLLs into a shared folder or specify every folder where they might exist.
If your plugins are being generated by other projects you can set them to build directly to your plugin folder or preferably have a post build task in the MyApplication project that copies the files into your project plugins folder.
You can easily do what you want by handling the AppDomain.CurrentDomain.AssemblyResolve event.
then inside the attached event handler just call:
Assembly assembly = Assembly.LoadFile(path: assemblyPath);
return assembly; // return resolved assembly
The assemblyPath is the absolute path to the DLL your program is trying to grab, and you could get that by scanning your DLL folder at runtime and then grabbing the path that contains the missing DLL name.
(This might be a obvious question but I wasn't sure what to ask Bing/Google)
In a VS2008 (C# Winforms) project there are numerous third party libraries that are referenced. The project uses 'Copy Local = True' so that the various DLL files end up in the same folder as the compiled application.
To clean things up I would like to modify the program so that the libraries are all under a subfolder.
For example:
C:\MyProgram\ -> main program folder
C:\MyProgram\Libraries -> DLL storage folder
How would I do this?
The best way to do this is to add an app.config file to your solution and setup private probing paths for each of the sub folders. The CLR will then look in these folders when searching for assemblies
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<probing privatePath="subFolder1;subFolder2;" />
</assemblyBinding>
</runtime>
</configuration>
Documentation
http://msdn.microsoft.com/en-us/library/823z9h8w(VS.80).aspx