如何将自定义 DLL 加载到 PowerShell
How to load a custom DLL into PowerShell
我一直在尝试将自定义 DLL 加载到 PowerShell 中,但没有成功。
正在创建我的 DLL based on this repository。我的最终目标是能够加载 Monster.dll
但我想我会从 Dice.dll
开始(因为它是一个静态的 class,几乎没有依赖项)。
我试过的
在 PowerShell 中:
cd C:\some\repo\dnd\dice\bin\Debug\netstandard2.1
$path = (pwd).Path
$path += "\Dice.dll"
[Reflection.Assembly]::LoadFile("$path")
GAC Version Location
--- ------- --------
False v4.0.30319 C:\some\repo\dnd\dice\bin\Debug\netstandard2.1\Dice.dll
然后我尝试调用简单的 Roll Dice 函数(看起来像这样)
[Dice.Dice]::Roll(20, 1)
它 returns 这个错误:
Unable to find type [Dice.Dice].
At line:1 char:1
+ [Dice.Dice]::Roll(20, 1)
+ ~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (Dice.Dice:TypeName) [], RuntimeException
+ FullyQualifiedErrorId : TypeNotFound
如果我尝试调用也会发生同样的事情:
[Dice]::Roll(20, 1)
我做错了什么?
编辑
有人建议我试试:
Add-Type -Path "$path"
它 returns 这个错误:
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 "$path"
+ ~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [Add-Type], ReflectionTypeLoadException
+ FullyQualifiedErrorId : System.Reflection.ReflectionTypeLoadException,Microsoft.PowerShell.Commands.AddTypeCommand
真正的"LoadExeption"是
Could not load file or assembly 'netstandard, Version=2.1.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51' or one of its
dependencies. The system cannot find the file specified.
评论中的另一个建议是 运行:
[appdomain]::currentdomain.getassemblies()
我能够从那个命令中找到这些数据
@{CodeBase=file:///C:/some/Repo/DnD/dice/bin/Debug/netstandard2.1/Dice.dll; FullName=Dice,
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null; EntryPoint=; DefinedTypes=; Evidence=System.Security.Policy.Evidence;
PermissionSet=<PermissionSet class="System.Security.PermissionSet"
version="1"
Unrestricted="true"/>
; SecurityRuleSet=Level2; ManifestModule=Dice.dll; ReflectionOnly=False;
Location=C:\some\Repo\DnD\dice\bin\Debug\netstandard2.1\Dice.dll; ImageRuntimeVersion=v4.0.30319;
GlobalAssemblyCache=False; HostContext=0; IsDynamic=False;
EscapedCodeBase=file:///C:/some/Repo/DnD/dice/bin/Debug/netstandard2.1/Dice.dll; ExportedTypes=;
IsFullyTrusted=True; CustomAttributes=; Modules=System.Reflection.RuntimeModule[]}
我也运行这个命令:
try {
([appdomain]::currentdomain.GetAssemblies() | where Location -match 'dice').gettypes()
} catch {
$_ | select *
}
PSMessageDetails :
Exception : System.Management.Automation.MethodInvocationException: Exception calling "GetTypes" with "0" argument(s):
"Unable to load one or more of the requested types. Retrieve the LoaderExceptions property for more
information." ---> System.Reflection.ReflectionTypeLoadException: Unable to load one or more of the requested
types. Retrieve the LoaderExceptions property for more information.
at System.Reflection.RuntimeModule.GetTypes(RuntimeModule module)
at System.Reflection.Assembly.GetTypes()
at CallSite.Target(Closure , CallSite , Object )
--- End of inner exception stack trace ---
at System.Management.Automation.ExceptionHandlingOps.CheckActionPreference(FunctionContext funcContext,
Exception exception)
at System.Management.Automation.Interpreter.ActionCallInstruction`2.Run(InterpretedFrame frame)
at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(InterpretedFrame frame)
at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(InterpretedFrame frame)
TargetObject :
CategoryInfo : NotSpecified: (:) [], MethodInvocationException
关键信息在"LoadException"消息中:
Could not load file or assembly 'netstandard, Version=2.1.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51' or one of its
dependencies. The system cannot find the file specified.
它说找不到程序集netstandard, Version=2.1.0.0
。这会阻止 PowerShell 加载 Dice,因为 Dice 是针对 .NET Standard 2.1 编译的。
我不确定通过 PowerShell 支持 .NET Standard 2.1 的细微差别。您可能需要更新版本的 PowerShell,或者您可能只需要安装正确的 .NET SDK/runtime 组件。
如果您未绑定到 .NET Standard 2.1,请尝试重新配置 C# 项目以面向 .NET Standard 2.0 或 .NET Framework 4.7(或更低版本)。
我想 post 我自己的答案,因为我想帮助其他人解决这个问题。
如果您遇到这样的错误,请务必按照以下步骤操作:
- 升级到最新版本的 .NET Core
- 将 PowerShell 升级到可用的最新版本。它必须支持您正在使用的 .NET Core 版本
- 调用该方法时,使用 PassThru 参数以获得更详细的错误
Add-Type -AssemblyName "C:\path\to\file.dll" -PassThru
同样,我的问题的根源在于在尝试使用 .NET Core 时使用 PowerShell 5。如果您查看 PowerShell 的安装位置,它包含自己的 .NET Core DLL,这将不同于您的全局安装。
我最终安装了 PowerShell 7 Preview,因为(在撰写本文时)它是唯一支持 .NET Core 3 的版本。*
我一直在尝试将自定义 DLL 加载到 PowerShell 中,但没有成功。
正在创建我的 DLL based on this repository。我的最终目标是能够加载 Monster.dll
但我想我会从 Dice.dll
开始(因为它是一个静态的 class,几乎没有依赖项)。
我试过的
在 PowerShell 中:
cd C:\some\repo\dnd\dice\bin\Debug\netstandard2.1
$path = (pwd).Path
$path += "\Dice.dll"
[Reflection.Assembly]::LoadFile("$path")
GAC Version Location
--- ------- --------
False v4.0.30319 C:\some\repo\dnd\dice\bin\Debug\netstandard2.1\Dice.dll
然后我尝试调用简单的 Roll Dice 函数(看起来像这样)
[Dice.Dice]::Roll(20, 1)
它 returns 这个错误:
Unable to find type [Dice.Dice].
At line:1 char:1
+ [Dice.Dice]::Roll(20, 1)
+ ~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (Dice.Dice:TypeName) [], RuntimeException
+ FullyQualifiedErrorId : TypeNotFound
如果我尝试调用也会发生同样的事情:
[Dice]::Roll(20, 1)
我做错了什么?
编辑
有人建议我试试:
Add-Type -Path "$path"
它 returns 这个错误:
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 "$path"
+ ~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [Add-Type], ReflectionTypeLoadException
+ FullyQualifiedErrorId : System.Reflection.ReflectionTypeLoadException,Microsoft.PowerShell.Commands.AddTypeCommand
真正的"LoadExeption"是
Could not load file or assembly 'netstandard, Version=2.1.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51' or one of its
dependencies. The system cannot find the file specified.
评论中的另一个建议是 运行:
[appdomain]::currentdomain.getassemblies()
我能够从那个命令中找到这些数据
@{CodeBase=file:///C:/some/Repo/DnD/dice/bin/Debug/netstandard2.1/Dice.dll; FullName=Dice,
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null; EntryPoint=; DefinedTypes=; Evidence=System.Security.Policy.Evidence;
PermissionSet=<PermissionSet class="System.Security.PermissionSet"
version="1"
Unrestricted="true"/>
; SecurityRuleSet=Level2; ManifestModule=Dice.dll; ReflectionOnly=False;
Location=C:\some\Repo\DnD\dice\bin\Debug\netstandard2.1\Dice.dll; ImageRuntimeVersion=v4.0.30319;
GlobalAssemblyCache=False; HostContext=0; IsDynamic=False;
EscapedCodeBase=file:///C:/some/Repo/DnD/dice/bin/Debug/netstandard2.1/Dice.dll; ExportedTypes=;
IsFullyTrusted=True; CustomAttributes=; Modules=System.Reflection.RuntimeModule[]}
我也运行这个命令:
try {
([appdomain]::currentdomain.GetAssemblies() | where Location -match 'dice').gettypes()
} catch {
$_ | select *
}
PSMessageDetails :
Exception : System.Management.Automation.MethodInvocationException: Exception calling "GetTypes" with "0" argument(s):
"Unable to load one or more of the requested types. Retrieve the LoaderExceptions property for more
information." ---> System.Reflection.ReflectionTypeLoadException: Unable to load one or more of the requested
types. Retrieve the LoaderExceptions property for more information.
at System.Reflection.RuntimeModule.GetTypes(RuntimeModule module)
at System.Reflection.Assembly.GetTypes()
at CallSite.Target(Closure , CallSite , Object )
--- End of inner exception stack trace ---
at System.Management.Automation.ExceptionHandlingOps.CheckActionPreference(FunctionContext funcContext,
Exception exception)
at System.Management.Automation.Interpreter.ActionCallInstruction`2.Run(InterpretedFrame frame)
at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(InterpretedFrame frame)
at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(InterpretedFrame frame)
TargetObject :
CategoryInfo : NotSpecified: (:) [], MethodInvocationException
关键信息在"LoadException"消息中:
Could not load file or assembly 'netstandard, Version=2.1.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51' or one of its
dependencies. The system cannot find the file specified.
它说找不到程序集netstandard, Version=2.1.0.0
。这会阻止 PowerShell 加载 Dice,因为 Dice 是针对 .NET Standard 2.1 编译的。
我不确定通过 PowerShell 支持 .NET Standard 2.1 的细微差别。您可能需要更新版本的 PowerShell,或者您可能只需要安装正确的 .NET SDK/runtime 组件。
如果您未绑定到 .NET Standard 2.1,请尝试重新配置 C# 项目以面向 .NET Standard 2.0 或 .NET Framework 4.7(或更低版本)。
我想 post 我自己的答案,因为我想帮助其他人解决这个问题。
如果您遇到这样的错误,请务必按照以下步骤操作:
- 升级到最新版本的 .NET Core
- 将 PowerShell 升级到可用的最新版本。它必须支持您正在使用的 .NET Core 版本
- 调用该方法时,使用 PassThru 参数以获得更详细的错误
Add-Type -AssemblyName "C:\path\to\file.dll" -PassThru
同样,我的问题的根源在于在尝试使用 .NET Core 时使用 PowerShell 5。如果您查看 PowerShell 的安装位置,它包含自己的 .NET Core DLL,这将不同于您的全局安装。
我最终安装了 PowerShell 7 Preview,因为(在撰写本文时)它是唯一支持 .NET Core 3 的版本。*