How to properly access the PrivateBinPath property of the current AppDomain? - c#

Since AppDomain.AppendPrivatePath() is obsolete, I'm trying to figure out how to specify a PrivateBinPath for the current AppDomain in my project without spinning up a whole new AppDomain, and being able to access it later.
I know I can set the PrivateBinPath on an AppDomainSetup object (which would be ok if I wanted to create a new AppDomain), and I also know that I can add it to my app.config like so:
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<probing privatePath=".\AlternateLookupPath" />
</assemblyBinding>
</runtime>
However, when adding this entry to my app.config, the AppDomain.CurrentDomain.SetupInformation.PrivateBinPath property is null.

use
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<probing privatePath="AlternateLookupPath" />
</assemblyBinding>
</runtime>
According to http://msdn.microsoft.com/en-us/library/823z9h8w.aspx the privatePath is already interpreted as "subdirectories of the application's base directory"... so I suspect that using .\ is somehow messing things up...

From the docs:
If the directories specified for
PrivateBinPath are not under
ApplicationBase, they are ignored.
So, you need to make sure the paths you are add are under ApplicationBase.
This only works with app.config however. If you need to do this at runtime, use the AssemblyResolve event as described in the docs:
http://msdn.microsoft.com/en-us/library/system.appdomain.assemblyresolve.aspx

Related

Is it possible to separate a C# executable and its dependent dlls in different folder and run the application?

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>

How to move referenced dlls to another folder C#

I'm trying to use CefSharp's Chromium Browser, but I don't want a clunk of files from cefsharp in its startup folder. I want to keep it in the bin folder, I don't know how.
Sorry, I'm a newbie at VS and all.
This is a partial solution to your problem. You can use the <probing> element in your run-time configuration, for specifying where to search for your assemblies, like in this example below, taken from the documentation:
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<probing privatePath="bin;bin2\subbin;bin3"/>
</assemblyBinding>
</runtime>
</configuration>
EDIT:
The rest of the answer is in this post here.

How to chage default directory of .dlls creating after built with runtime and probing?

I want to move all .dlls to "lib" folder after building my application. Default program creates them in directory:
bin\Debug\netcoreapp2.2
And this is directory where I want to place my .dlls:
bin\Debug\netcoreapp2.2\lib
I create script which moves my .dlls to this folder and put it in post-built event. It works correctly.
Next, I add runtime to my app.config file like I saw in many tutorials and articles on stackoverflow.
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<probing privatePath="lib"/>
</assemblyBinding>
</runtime>
But, after building and starting my program, console says:
The application to execute does not exist:
app\bin\Debug\netcoreapp2.2\myDLL.dll
I want to know what's wrong with my application? How can I change the directory in which program is looking for .dlls?
I guess what you need is the codebase element in the configuration.
From documentation, If the assembly has a strong name, the codebase setting can be anywhere on the local intranet or the Internet. If the assembly is a private assembly, the codebase setting must be a path relative to the application's directory.
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="myAssembly"
publicKeyToken="32ab4ba45e0a69a1"
culture="neutral" />
<codeBase version="2.0.0.0"
href="http://www.litwareinc.com/myAssembly.dll"/>
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
Hope this helps.

Dependent Assembly loading via configuration

I have a visual studio project with is running absolutely fine.
But a new client requirement comes up for deployment for placing the different dlls in different folders.
We have a framework dll which can be used in a different project. There are some third-party dlls on which this framework dll depends upon. So when I use this dll from my project every dependent dll is copied to my local on the build as CopyLocal property is true.
But now with new requirement we can not have CopyLocal property set as True. The client wants no local copy of any dll, rather he wants framework related dll in some location. When I am doing this the dependent DLL's are not getting loded.
I know I have two options:
I can put them in GAC, but I don't want to do this as I want them to support xcopy.
Using reflection(But I am not sure of this that is this the right approach)
Can we do anything using configurations??
You can configure assembly probing paths using the <probing> configuration element:
Specifies application base subdirectories for the common language runtime to search when loading assemblies.
Example from MSDN:
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<probing privatePath="bin;bin2\subbin;bin3"/>
</assemblyBinding>
</runtime>
</configuration>
However, if the assemblies in question reside outside the application base ("which is the root location where the application is being executed"), you have the <codeBase> configuration element:
Specifies where the common language runtime can find an assembly.
Example from MSDN:
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="myAssembly"
publicKeyToken="32ab4ba45e0a69a1"
culture="neutral" />
<codeBase version="2.0.0.0"
href="http://www.litwareinc.com/myAssembly.dll"/>
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
For the exact details of how the runtime locates assemblies you can refer to this MSDN article.
As OP pointed out, unfortunately codeBase element is a usable option for strong named assemblies only. For private assemblies you need a workaround. Some viable ideas can be found in this discussion such as:
file system links (NTFS junction point) + probing element or AppDomainSetup.PrivateBinPath
AppDomain.CurrentDomain.AssemblyResolve event
I've tested the latter and can confirm it works:
AppDomain.CurrentDomain.AssemblyResolve += (s, e) =>
Assembly.LoadFile(Path.Combine(Settings.Default.AssemblyPath, Path.ChangeExtension(e.Name.Substring(0, e.Name.IndexOf(',')), ".dll")));

How to dynamically specify the path to the class library DLL?

Target: dynamically set the path to the class library c#.
For example, if the path to the DLL is not found.
Find DLL manually and specify the path where to load.
You can add a path to the app config that is searched for DLLs. Here's an example:
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<probing privatePath="C:\myDLLDirectory\" />
</assemblyBinding>
</runtime>
</configuration>
See here for more information and ideas. There are several ways to do it: http://support.microsoft.com/kb/837908

Categories