Powershell 和 .NET5.0 无法加载程序集 [英] Powershell and .NET5.0 fails loading the assembly

查看:57
本文介绍了Powershell 和 .NET5.0 无法加载程序集的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

背景

使用visual studio 2019 v16.10.3我已经创建了这个(标准MS示例源)类库并成功编译成MyMathLib.DLL

使用系统;命名空间 MyMathLib{公共类方法{公共方法(){}public static int Sum(int a, int b){返回 a + b;}public int Product(int a, int b){返回 a * b;}}}

我的 MyMathLib.csproj 文件如下所示:

<属性组><TargetFramework>net5.0</TargetFramework></PropertyGroup></项目>

然后我想尝试使用以下脚本使用 powershell 执行此代码:

[string]$assemblyPath='S:SourcesResearchHansDotNetFromPowerShellMyMathLibMyMathLibinDebug
et5.0MyMathLib.dll'添加类型 -Path $assemblyPath

当我运行这个时我得到一个错误,并通过查询LoaderExceptions的错误来询问发生了什么:

PS C:WINDOWSsystem32>S:SourcesResearchHansDotNetFromPowerShellTestDirectCSharpScript2.ps1附加类型:Kan een of meer van de gevraagde typen niet laden.Haal de LoaderExceptions-eigenschap op voor meer informatie.在 S:SourcesResearchHansDotNetFromPowerShellTestDirectCSharpScript2.ps1:2 char:1+ 添加类型 -Path $assemblyPath+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+ CategoryInfo : NotSpecified: (:) [Add-Type], ReflectionTypeLoadException+ FullQualifiedErrorId : System.Reflection.ReflectionTypeLoadException,Microsoft.PowerShell.Commands.AddTypeCommandPS C:WINDOWSsystem32>$Error[0].Exception.LoaderExceptionsKan bestand of assembly System.Runtime, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a of een van de afhankelijkheden hiervan niet laden.Het 系统 kan het opgegeven bestand niet vinden.PS C:WINDOWSsystem32>

(抱歉,荷兰语窗口消息:类似无法加载一种或多种类型"和加载程序异常无法加载文件或程序集System.Runtime"等...

我在 SO 上看到了很多相关的问题,但它们通常很旧并且不涉及 .NET5.0

这有效

当我像下面这样直接编译示例源时,它工作得很好.

$code = @"使用系统;命名空间 MyNameSpace{公共课响应者{public static void StaticRespond(){Console.WriteLine(静态响应");}公共无效响应(){Console.WriteLine(实例响应");}}}"@# 检查会话中之前没有添加过类型,否则会引发异常if (-not ([System.Management.Automation.PSTypeName]'MyNameSpace.Responder').Type){添加类型 -TypeDefinition $code -Language CSharp;}[MyNameSpace.Responder]::StaticRespond();$instance = 新对象 MyNameSpace.Responder;$instance.Respond();

为什么?

整个想法都有一个概念证明,我可以使用我的 .NET5 库使用例如PowerShell 脚本.我实际上必须加载一个更复杂的程序集,但这个过于简化的示例似乎是我目前的主要问题.

问题

我错过了什么?- 我如何让它工作?

TIA 对我的包容.

解决方案

您没有说明您使用的是哪个版本的 Powershell.但是,我可以通过以下方式重现错误.

在 VS 2019 中,创建一个 Class Library(C# Windows 库).

从Class1.cs"重命名类到Methods.cs"

Methods.cs

使用系统;命名空间 MyMathLib{公共类方法{public int Sum(int a, int b){返回 a + b;}public int Product(int a, int b){返回 a * b;}}}

编译.

  • 打开Windows Powershell
  • 输入:(Get-Host).version

然后输入以下内容:

PS C:UsersTest>[string]$assemblyPath=C:TempMyMathLib.dll"PS C:用户测试>添加类型 -Path $assemblyPath

导致以下错误:

Add-Type:无法加载一种或多种请求的类型.检索 LoaderExceptions 属性以获取更多信息.在行:1 字符:1+ 添加类型 -Path $assemblyPath+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+ CategoryInfo : NotSpecified: (:) [Add-Type], ReflectionTypeLoadException+ FullQualifiedErrorId : System.Reflection.ReflectionTypeLoadException,Microsoft.PowerShell.Commands.AddTypeCommand

发生这种情况是因为 Windows Powershell 5.1 不支持 .NETCore 5 - 仅在版本 6 及更高版本上.对于 Powershell 5.1 或以下版本,必须使用 .NETFramework.

参见 解决 PowerShell 模块程序集依赖冲突,声明如下:

<块引用>

PowerShell 和 .NET... 一般来说,PowerShell 5.1 及以下版本在 .NET Framework 上运行,而 PowerShell 6 及以上版本在 .NET Core 上运行.这两个.NET 的实现加载和处理程序集的方式不同.

参见 在 Windows 上安装 PowerShell 了解如何获取最新版本的 Powershell.

Powershell 7.1.3 中,可以通过执行以下操作从 MyMathLib.dll 调用方法:

PS C:UsersTest>[string]$assemblyPath=C:TempMyMathLib.dll"PS C:用户测试>添加类型 -Path $assemblyPathPS C:用户测试>$m1 = 新对象 -TypeName MyMathLib.MethodsPS C:用户测试>$m1.Sum(2,3)

注意:由于类/方法不是静态的,需要使用$m1 = New-Object -TypeName MyMathLib.Methods>

但是,如果它是静态的(如下所示):

MyMathLib.cs

使用系统;命名空间 MyMathLib{公共静态类方法{public static int Sum(int a, int b){返回 a + b;}public static int Product(int a, int b){返回 a * b;}}}

然后可以在 Powershell 中执行以下操作:

PS C:UsersTest>[string]$assemblyPath=C:TempMyMathLib.dll"PS C:用户测试>添加类型 -Path $assemblyPathPS C:用户测试>[MyMathLib.Methods]::Sum(3,2)

Background

Using visual studio 2019 v16.10.3 I have created this (standard MS example source) class library and successfully compiled into MyMathLib.DLL

using System;

namespace MyMathLib
{
    public class Methods
    {
        public Methods()
        {
        }
        public static int Sum(int a, int b)
        {
            return a + b;
        }
        public int Product(int a, int b)
        {
            return a * b;
        }
    }
}

My MyMathLib.csproj file looks like this:

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>net5.0</TargetFramework>
  </PropertyGroup>
</Project>

And then I want to try executing this code using powershell using the following script:

[string]$assemblyPath='S:SourcesResearchHansDotNetFromPowerShellMyMathLibMyMathLibinDebug
et5.0MyMathLib.dll'
Add-Type -Path $assemblyPath

When I run this I get an error, and ask what's going on by querying the error for LoaderExceptions:

PS C:WINDOWSsystem32> S:SourcesResearchHansDotNetFromPowerShellTestDirectCSharpScript2.ps1
Add-Type : Kan een of meer van de gevraagde typen niet laden. Haal de LoaderExceptions-eigenschap op voor meer informatie.
At S:SourcesResearchHansDotNetFromPowerShellTestDirectCSharpScript2.ps1:2 char:1
+ Add-Type -Path $assemblyPath
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [Add-Type], ReflectionTypeLoadException
    + FullyQualifiedErrorId : System.Reflection.ReflectionTypeLoadException,Microsoft.PowerShell.Commands.AddTypeCommand
 

PS C:WINDOWSsystem32> $Error[0].Exception.LoaderExceptions
Kan bestand of assembly System.Runtime, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a of een van de afhankelijkhed
en hiervan niet laden. Het systeem kan het opgegeven bestand niet vinden.

PS C:WINDOWSsystem32> 

(Sorry for dutch windows messages: something like "Cannot load one or more of the types" and the loader exception Cannot load file or assembly "System.Runtime" etc...

I have seen many related issues on SO, but they are usually quite old and do not refer to .NET5.0

This works

When I directly compile the example source like below, it works just fine.

$code = @"
using System;

namespace MyNameSpace
{
    public class Responder
    {
        public static void StaticRespond()
        {
            Console.WriteLine("Static Response");
        }

        public void Respond()
        {
            Console.WriteLine("Instance Respond");
        }
    }
}
"@

# Check the type has not been previously added within the session, otherwise an exception is raised
if (-not ([System.Management.Automation.PSTypeName]'MyNameSpace.Responder').Type)
{
    Add-Type -TypeDefinition $code -Language CSharp;
}

[MyNameSpace.Responder]::StaticRespond();

$instance = New-Object MyNameSpace.Responder;
$instance.Respond();

Why?

The whole Idea to have a proof of concept that I can utilize my .NET5 libraries using e.g. powershell scripts. I actually have to load a much more complicated assembly, but this oversimplified example seems to be my primary issue at the moment.

The question

What am I missing? - How do I get this to work?

TIA for bearing with me.

解决方案

You didn't state what version of Powershell that you're using. However, I can reproduce the error by the following.

In VS 2019, create a Class Library (C# Windows Library).

Rename the class from "Class1.cs" to "Methods.cs"

Methods.cs

using System;

namespace MyMathLib
{
    public class Methods
    {
        public int Sum(int a, int b)
        {
            return a + b;
        }
        public int Product(int a, int b)
        {
            return a * b;
        }
    }
}

Compile.

  • Open Windows Powershell
  • Type: (Get-Host).version

Then type the following:

PS C:UsersTest> [string]$assemblyPath="C:TempMyMathLib.dll"
PS C:UsersTest> Add-Type -Path $assemblyPath

which results in the following error:

Add-Type : Unable to load one or more of the requested types. Retrieve the LoaderExceptions property for more information.
At line:1 char:1
+ Add-Type -Path $assemblyPath
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [Add-Type], ReflectionTypeLoadException
    + FullyQualifiedErrorId : System.Reflection.ReflectionTypeLoadException,Microsoft.PowerShell.Commands.AddTypeCommand

This occurs because .NETCore 5 isn't supported by Windows Powershell 5.1 - only on versions 6 and above. For Powershell 5.1 or below, it's necessary to use .NETFramework instead.

See Resolving PowerShell module assembly dependency conflicts which states the following:

PowerShell and .NET ... In general, PowerShell 5.1 and below run on .NET Framework, while PowerShell 6 and above run on .NET Core. These two implementations of .NET load and handle assemblies differently.

See Installing PowerShell on Windows for how to get the latest version of Powershell.

In Powershell 7.1.3, one can call a method from MyMathLib.dll by doing the following:

PS C:UsersTest> [string]$assemblyPath="C:TempMyMathLib.dll"
PS C:UsersTest> Add-Type -Path $assemblyPath
PS C:UsersTest> $m1 = New-Object -TypeName MyMathLib.Methods
PS C:UsersTest> $m1.Sum(2,3)

Note: Since the class/methods aren't static, it's necessary to create an instance by using $m1 = New-Object -TypeName MyMathLib.Methods

However, if it's static (as shown below):

MyMathLib.cs

using System;

namespace MyMathLib
{
    public static class Methods
    {
        public static int Sum(int a, int b)
        {
            return a + b;
        }
        public static int Product(int a, int b)
        {
            return a * b;
        }
    }
}

Then one can do the following in Powershell:

PS C:UsersTest> [string]$assemblyPath="C:TempMyMathLib.dll"
PS C:UsersTest> Add-Type -Path $assemblyPath
PS C:UsersTest> [MyMathLib.Methods]::Sum(3,2)

这篇关于Powershell 和 .NET5.0 无法加载程序集的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆