0

I've researched a lot on stackoverflow and no one really explained what to do in my case.

I have application that is using a TFS Api, and it is using a Nuget packages that contains dll like Microsoft.TeamFoundation.*.dll.

Here comes the tricky part - When I run application from debug everything is working fine since CLR is loading dlls from my , BUT when I deploy application and start using it, it loads dlls from the GAC if any of those dlls exists in GAC.

This causes numerous errors since it loads different versions e.g. Microsoft.TeamFoundation.1stdll.dll with version 11.2.2302 then Microsoft.TeamFoundation.2nddll.dll with version 11.0.2123 and there are cases when it starts with 10, and then asking for a reference 10 dll to resolve issue and I end up with exception.

What I did?

I've tried to point to probing path with without success. As soon as it finds for example version 11.0.2.1 in GAC and 11.3.1.2 in probing it resolves dll with GAC one.

I've tried as someone explained to create a new appdomain and to share dlls between domains but I've hit the dead end, no matter what I've tried it loaded it from the GAC. I've also tried to load dlls at entry point of my app, and than to redirect it to my path and resolved it. Again no success. I've tried to trick application and at resolving point return null for publicKeyToken in order to tell it that I am using a non-signed dll, in which case it wouldn't look at the GAC, but had no luck. I've tried to remove signing with Nirsoft snremove.exe and guess what? No success either.

I am looking for a code that will no matter what force my application to use my dlls instead of one in GAC. I want to avoid that during runtime it does not randomly pick up a 11.00.xxxx version but instead use my specific 11.92.21212.2 even when it has bigger or in some cases lower versions.

The only thing that I cant accept as a possible solution is to manually configure CLR interfaces for resolving and loading assemblies in C++ as someone mentioned on stackoverflow before.

kokoshaner
  • 64
  • 10
  • 2
    Are all these version numbers assembly versions or file versions? There is no way to bypass loading from the GAC once a compatible version is found in the GAC, but you might be able to use assembly binding redirects to select the correct version. You may also want to look at disabling publisher policy for redirects. – Mike Zboray Nov 30 '17 at 08:24
  • 1
    The GAC is exactly about loading the right version. The version number is part of the reference and so it seems off that it would load a different version. There might be a policy file that allows that, but that shouldn't forward to an incopatible assembly. – Sefe Nov 30 '17 at 08:26
  • You can try set assembly binding redirects to redirect all versions of that specific assembly to version 11.92.21212.2. Then even if it won't load it from your directory and from GAC - at least it will load exactly the version you expect. – Evk Nov 30 '17 at 09:12
  • @mikez Already tried all that you've said – kokoshaner Nov 30 '17 at 10:03
  • @Sefe well, the GAC is loading the version 11. As I understand Microsoft can recognize major versions, if I redirect binding for example for scope of versions 1-15, and set new version to be 11. It does know that by the app config. The problem is that when it finds out a dll in GAC that also has major version 11 it takes that dll, no matter why. Other dlls that are not found in GAC are loaded normally from my probing dir. – kokoshaner Nov 30 '17 at 10:09
  • @Safe - For example i have 20 dlls all version 11.90.1111 but there are 2 of them also in GAC but version 11.00.1111 and it loads first 10 of my dlls 11.90, than when it comes to the issued two, it loads them from GAC 11.00.xxx and the rest one are also loaded from my probing dir. The issue is that I need 11.90, not 11.00 that was loaded from GAC. Because it contains methods that I am using. – kokoshaner Nov 30 '17 at 10:09
  • @Evk, already did set up binding redirect in appconfig for a scope of dlls, ignored policy, tried to set up particular path, tried to set up a specific version of dll as a new version in binding redirect. Those are previously explained in other posts on stackoverflow, but as it turns out none of them are a working solution. I need someone who had this issue and successfully resolved it. – kokoshaner Nov 30 '17 at 10:13

1 Answers1

0

One thing I can think of is you can try is to limit the permissions of the new Application domain you load to not have access to the file system, drive, or to the GAC path more precisely, for example on the first call into a method in the new domain or a constructor set the permissions like it's done here.

Then you can embed the needed assemblies in the Resources of the application and use the AssemblyResolve event to load them like this.

MarkovskI
  • 1,489
  • 2
  • 21
  • 25