Powershell - 在应用程序配置文件中找不到程序集绑定重定向

 歪友46300606 发布于 2022-12-14 10:43

不是100%与32/64位问题相关,但是如果有人对工作程序集重定向解决方案感兴趣,请查看Powershell配置程序集重定向.

您可以使用PowerShell代码执行自定义程序集重定向

$FSharpCore = [reflection.assembly]::LoadFrom($PSScriptRoot + "\bin\LIBRARY\FSharp.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)

我首先FSharp.Core从某个地方加载正确的版本,因为GAC中的版本已经过时了(我想这可能也是你的情况)

您还可以检查我的项目中的实际测试用法.

2 个回答
  • 不是100%与32/64位问题相关,但是如果有人对工作程序集重定向解决方案感兴趣,请查看Powershell配置程序集重定向.

    您可以使用PowerShell代码执行自定义程序集重定向

    $FSharpCore = [reflection.assembly]::LoadFrom($PSScriptRoot + "\bin\LIBRARY\FSharp.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)
    

    我首先FSharp.Core从某个地方加载正确的版本,因为GAC中的版本已经过时了(我想这可能也是你的情况)

    您还可以检查我的项目中的实际测试用法.

    2022-12-14 10:45 回答
  • 根据@ davidpodhola非常有用的答案,我开始在我的psm1模块文件中添加这样的东西.如果您的新程序集已经加载(例如通过Import-Module),这应该可以:

    if (!("Redirector" -as [type]))
    {
    $source = 
    @'
    using System;
    using System.Linq;
    using System.Reflection;
    using System.Text.RegularExpressions;
    
    public class Redirector
    {
        public readonly string[] ExcludeList;
    
        public Redirector(string[] ExcludeList = null)
        {
            this.ExcludeList  = ExcludeList;
            this.EventHandler = new ResolveEventHandler(AssemblyResolve);
        }
    
        public readonly ResolveEventHandler EventHandler;
    
        protected Assembly AssemblyResolve(object sender, ResolveEventArgs resolveEventArgs)
        {
            Console.WriteLine("Attempting to resolve: " + resolveEventArgs.Name); // remove this after its verified to work
            foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies())
            {
                var pattern  = "PublicKeyToken=(.*)$";
                var info     = assembly.GetName();
                var included = ExcludeList == null || !ExcludeList.Contains(resolveEventArgs.Name.Split(',')[0], StringComparer.InvariantCultureIgnoreCase);
    
                if (included && resolveEventArgs.Name.StartsWith(info.Name, StringComparison.InvariantCultureIgnoreCase))
                {
                    if (Regex.IsMatch(info.FullName, pattern))
                    {
                        var Matches        = Regex.Matches(info.FullName, pattern);
                        var publicKeyToken = Matches[0].Groups[1];
    
                        if (resolveEventArgs.Name.EndsWith("PublicKeyToken=" + publicKeyToken, StringComparison.InvariantCultureIgnoreCase))
                        {
                            Console.WriteLine("Redirecting lib to: " + info.FullName); // remove this after its verified to work
                            return assembly;
                        }
                    }
                }
            }
    
            return null;
        }
    }
    '@
    
        $type = Add-Type -TypeDefinition $source -PassThru 
    }
    
    #exclude all powershell related stuff, not sure this strictly necessary
    $redirectExcludes = 
        @(
            "System.Management.Automation", 
            "Microsoft.PowerShell.Commands.Utility",
            "Microsoft.PowerShell.Commands.Management",
            "Microsoft.PowerShell.Security",
            "Microsoft.WSMan.Management",    
            "Microsoft.PowerShell.ConsoleHost",
            "Microsoft.Management.Infrastructure",
            "Microsoft.Powershell.PSReadline",
            "Microsoft.PowerShell.GraphicalHost"
            "System.Management.Automation.HostUtilities",
    
            "System.Management.Automation.resources",
            "Microsoft.PowerShell.Commands.Management.resources",
            "Microsoft.PowerShell.Commands.Utility.resources",
            "Microsoft.PowerShell.Security.resources",
            "Microsoft.WSMan.Management.resources",
            "Microsoft.PowerShell.ConsoleHost.resources",
            "Microsoft.Management.Infrastructure.resources",
            "Microsoft.Powershell.PSReadline.resources",
            "Microsoft.PowerShell.GraphicalHost.resources",
            "System.Management.Automation.HostUtilities.resources"
        )
    try
    {
        $redirector = [Redirector]::new($redirectExcludes)
        [System.AppDomain]::CurrentDomain.add_AssemblyResolve($redirector.EventHandler)
    }
    catch
    {
        #.net core uses a different redirect method
        write-warning "Unable to register assembly redirect(s). Are you on ARM (.Net Core)?"
    }
    

    更新:Powershell似乎有一个错误,即只需注册程序集解析scriptblock就可能在调用Out-GridView等命令时导致StackOverflowException.我更新了代码以使用使用Add-Type编译的版本,似乎可以解决问题.

    2022-12-14 10:45 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有