Making calls to different version of different assembly - c#

I have 2 versions of same dlls. Say named, Test.dll. I want to call 2 dlls from my console application.
I tried to use Extern alias. But it is calling new dll. I am calling these 2 dlls from my DAL class.
Any help would be appreciated.
Thanks,

This is not the default way of how you do things in .net, therefore coding will not be easy in such a manner. As #Johnathon Reinhart says in his answer, you will have to use Assembly.Load (by passing the fully qualified assembly name to the function).
Like this:
Assembly asmOld = Assembly.Load("MyAssembl, Version=1.0.0.1, Culture=neutral, PublicKeyToken=ab1234567defabc1");
Assembly asmNew = Assembly.Load("MyAssembl, Version=2.0.0.1, Culture=neutral, PublicKeyToken=ab1234567defabc1")
Moreover, you will have to keep reference to both assemblies and then use Assembly.CreateInstance to create instances of the types you need. After that, you will have to call members using reflection (something like this). Like this:
Ojbect objOld = asmOld.CreateInstance("MyApp.Namespace.Classname");
Ojbect objNew = asmNew.CreateInstance("MyApp.Namespace.Classname");
objOld.GetType().InvokeMember("TestMethod", BindingFlags.InvokeMethod,null,obj,null);
objNew.GetType().InvokeMember("TestMethod", BindingFlags.InvokeMethod,null,obj,null);
To improve your code writing, you could use the LateCall from Microsoft.VisualBasic.CompilerServices to work with your objects. There is a nice wrapper for that by Andy Adinborough - http://andy.edinborough.org/Use-Late-Binding-in-C-Now-without-NET-4-0

I'm assuming that these DLLs are .NET assemblies, and not just standard C DLLs.
If so, I think you can specifically load the assembly with the static Assembly.LoadFrom(string assemblyFile). Then I think you can get a module from that assembly with Assembly.GetModule().

you can use Assembly.LoadFile or using alias
Loading Multiple Versions of same Assembly
Using different versions of the same dll in one application

Related

Load Assembly without culture and version

I know that recommended way of loading assemblies is:
Assembly SampleAssembly = Assembly.Load
("SampleAssembly, Version=1.0.2004.0, Culture=neutral, PublicKeyToken=8744b20f8da049e3")
But, what if I don't know which version of assembly exists in GAC (for example NpSql or MySql.Data can have different versions in different machines)?
Then I might want to load it without specifying version, culture and public key token.
Is that possible? (I know about LoadWithPartialName but it is now obsolete).
It seems we can use Assembly.Load(AssemblyName) but it is not recommended way to do it.

Getting a reference to System.String from System.Runtime.dll instead of from mscorlib

I have a reference to System.Runtime.dll that I got using Assembly.ReflectionOnlyLoad.
When I call .GetType("System.String") on it, I get the System.String type in mscorlib, instead of the one in System.Runtime, which will cause me problems as I'll generate the wrong IL. Is there any other way to do this?
What you see there is the result of assembly unification. When you're emitting assemblies using the System.Reflection APIs, there is no easy way to avoid leaking metadata (e.g. Type) references from your environment into the resulting assembly. That's because the S.R Api's were meant for runtime code generation, not for generating some output to be saved.
You may try using something like Mono.Cecil which is a lot more suited for that purpose.

manage memory using marshalbyrefobject

I have a method that performs a search in both the local assembly and in the current directory. It is looking for a class based on the name provided (reflection). However I now want to only load the classes/dlls that I am looking for into memory as opposed to loading them all and selecting the one that I want from it.
I have been told that marshalbyrefobject could be used to do this. [Below is the code I am currently using]
The solution would be to create 2 app domains and have one load all the assembiles and do the checks then unload on of the app domains, though im not sure how to go about doing that.
To my limited knowledge, you can avoid loading the assemblies by querying them beforehand using the Assembly class.
A full working model would look like this:
1 - Collect information through the Assembly class
Assembly File:
Assembly assembly = Assembly.ReflectionOnlyLoadFrom(fileName);
Local assembly:
Assembly myAssembly = Assembly.GetExecutingAssembly();
2 - Iterate through the classes present on each Assembly reference
Assembly mscorlib = typeof(string).Assembly;
foreach (Type type in mscorlib.GetTypes())
{
Console.WriteLine(type.FullName);
}
3 - After choosing which assembly to use, Load it into your Application Domain
Assembly assembly = Assembly.Load(fullAssemblyName);
or
Assembly assembly = Assembly.LoadFrom(fileName);
Examples copied from the following post, so feel free to upvote the responses there if you feel they contributed to solve your issue!
C#: List All Classes in Assembly

Castle DynamicProxy Interceptor having problems with different assemblies

I have a scenario like this:
I'm using interceptor to catch calls to a class that is inside assembly (let's call it Feature) that is referenced by main project. Assembly Feature is installed by NuGet (it's not public but our internal one) and has reference to another assembly (let's call it Core). Main project is referencing assembly Core as well. Core contains class definition that is used as an argument type of one of the intercepted methods.
It all works fine as long as Main project and Feature are referencing the same version of Core library. Problem arises when this versions are different and intercepted method uses types from Core as a method arguments.
In this situation, an exception is thrown that states A strongly-named assembly is required.:
[FileLoadException: Could not load file or assembly 'Core, Version=0.2.2.30, Culture=neutral, PublicKeyToken=null' or one of its dependencies. A strongly-named assembly is required. (Exception from HRESULT: 0x80131044)]
Castle.Proxies.Invocations.IBasketService_Update.InvokeMethodOnTarget() +0
Castle.DynamicProxy.AbstractInvocation.Proceed() +116
Project.Basket.BasketServiceUpdatedInterceptor.Intercept(IInvocation invocation) in c:\(...)\Basket\BasketServiceUpdatedInterceptor.cs:20
Castle.DynamicProxy.AbstractInvocation.Proceed() +604
Castle.Proxies.IBasketServiceProxy.Update(ProductId productId, UInt16 quantity) +210 (...)
Where version of Core 0.2.2.30 is a version that assembly Feature is expecting, main project is using for example version 0.2.2.31. Castle DynamicProxy is not able to find Core with version 0.2.2.30 and that's right because this exact assembly is not deployed to bin folder.
Please note that different versions of Core are a situation perfectly normal in our scenario. Feature assembly is expecting version higher than specified - not exact version.
I'm not sure whether DynamicProxy should be less rigid in it's assembly expectations are I do have to accept this limitation. I've written simple proxy class to overcome this problem so it does not block me anymore yet it blocks us from using DynamicProxy in our solutions.
The problem is caused by the fact that DP was generated against a signed assembly and then an unsigned version of the assembly is being used.
The solution is either to ensure that you use signed assembly in both cases, or to force DynamicProxy to only generate unsigned assembly.

How to use Easyhook with non managed executable

I am trying to do some hooking in c# (I'd rather not use Detours or c++) so i have been using EasyHook.
https://easyhook.github.io/
However When i'm doing this
Config.Register( "This description can be anything.", #"SomePathToAnExecutable.exe", "MyInjectionDll.dll");
I get the error:
There was an error while connecting to
target:
System.BadImageFormatException: Unable
to load given assembly
[SomePathToAnExecutable.exe] for
reflection.
Is this a valid NET assembly? --->
System.BadImageFormatException: Could
not load file or assembly
[SomePathToAnExecutable.exe] or one of
its dependencies. The module was
expected to contain an assembly
manifest.
Question 1) Am I right in thinking that SomePathToAnExecutable is the process that you want to hook into???
Question 2) Does the executable have to be managed code then??
I've also asked at on the codeplex project site, but no response.
http://easyhook.codeplex.com/Thread/View.aspx?ThreadId=235616
Answer 1) No. Config.Register registers managed assemblies with the GAC. Thus you register all assemblies participating from your code. This includes the dll you want to inject and the assembly that provides the common interface for the IPCServer. For my it looks like this one for example:
Config.Register("MyHook",
Path.Combine(startupPath, "HookManager.dll"),
Path.Combine(startupPath, "NetworkIncomingHook.dll"),
Path.Combine(startupPath, "NetworkOutgoingHook.dll")
);
The HookManager.dll contains the interface I use to create the IPCServer (and where all messages are send to from the hooked functions). The NetworkIncomingHook.dll and NetworkOutgoingHook.dll are both dlls I inject into my programm. This is done by RemoteHooking.Inject.
2) No. You can hook unmanaged assemblies aswell.

Categories