Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
546 views
in Technique[技术] by (71.8m points)

.net - Powershell config assembly redirect

I have a custom .NET assembly with some powershell cmdlets than I use for common domain related tasks. I've just created a new cmdlet that references a 3rd party library that has a reference to Newtonsoft.Json 4.5.0.0. However one of my other projects uses the latest version of json.net (6.0.0.0). So at runtime in powershell fusion throws an error saying it can't load newtonsoft.json 4.5.0.0.

I've tried creating a powershell.exe.config and putting an assembly redirect in there:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
        <assemblyIdentity name="Newtonsoft.Json", Culture=neutral,     PublicKeyToken=30ad4fe6b2a6aeed/>
        <bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
      </dependentAssembly>
    </assemblyBinding>
  </runtime>
</configuration>

but this doesn't seem to work. The fusion log does state that it is looking in this new config file for powershell but it doesn't seem to be picking up the redirect.

Bit stumped for solutions here. Any clues what the problem might be? This same redirect works in some of my business services that would otherwise have the same issue (they also use this 3rd party lib and json.net 6).

Cheers

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Not sure how it worked more than year ago, however today on Windows 10 using PowerShell 5.0.10240.16384 the only way I was able to do assembly redirect (in my case from FSharp.Core 4.3 to 4.4) was to manually resolve assembly dependencies based on Manually resolving assembly dependencies in PowerShell. I tried every other solutions like creating the powershell.exe.config file or trying to load some other *.config file, but nothing of those worked.

The only "gotcha" (at lease for me) was, that since I do not have FSharp.Core 4.3 anywhere, I needed to manually redirect it to 4.4. I ended up using

$FSharpCore = [reflection.assembly]::LoadFrom($PSScriptRoot + "inLIBRARYFSharp.Core.dll") 

$OnAssemblyResolve = [System.ResolveEventHandler] {
  param($sender, $e)

  # from:FSharp.Core, Version=4.3.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
  # to:  FSharp.Core, Version=4.4.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
  if ($e.Name -eq "FSharp.Core, Version=4.3.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a") { return $FSharpCore }
  
  foreach($a in [System.AppDomain]::CurrentDomain.GetAssemblies())
  {
    if ($a.FullName -eq $e.Name)
    {
      return $a
    }
  }
  return $null
}

[System.AppDomain]::CurrentDomain.add_AssemblyResolve($OnAssemblyResolve)

where I am first loading the correct version of FSharp.Core from somewhere as the version in the GAC is old (I guess this might be your case too)

You can also check the real test usage in my project.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...