Cam*_*ker 3 dll powershell dllimport
[void] CreateSession() {
try {
# Load WinSCP .NET assembly
Add-Type -Path (Join-Path $PSScriptRoot "\winscp\WinSCPnet.dll")
# Setup session options
$this.sessionOptions = New-Object WinSCP.SessionOptions -Property @{
Protocol = [WinSCP.Protocol]::Sftp
Run Code Online (Sandbox Code Playgroud)
在上面的代码部分中,我遇到了有关“[WinSCP.Protocol]”的“TypeNotFound”错误消息。
14 | Protocol = [WinSCP.Protocol]::Sftp
| ~~~~~~~~~~~~~~~
| Unable to find type [WinSCP.Protocol].
Run Code Online (Sandbox Code Playgroud)
.dll 文件可以正确加载,我之前已经验证过这一点。我知道发生的情况是 PowerShell“解析器”抛出错误,因为它在加载时无法识别 WinSCP 库。我尝试添加模块和清单,但找不到如何正确执行此操作的简单示例。另外,我运行的是 PowerShell 5.x 还是 7.x 并不重要。我想要的只是加载这个 DLL,这样我就可以使用其中的类/函数。为什么在 PowerShell 中加载 DLL 如此困难?
我需要做什么才能让这个 WinSCP DLL 在运行时加载并且不抛出错误?
几年前,有人在此网站上提出了一个非常类似的问题,但没有答案。
我正在寻找一个关于如何将 DLL 文件加载到脚本中的真实示例。链接的问题不适当地这样做。为什么我需要创建清单模块来导入 DLL?
\n
长话短说:博士:
\n该问题源于尝试通过类型文字(例如)在class定义中引用刚刚加载的 WinSCP 类型,如下所述。[WinSCP.Protocol]
完全不使用es 而是使用函数可以绕过这个问题。class
\n\n我正在寻找一个关于如何将 DLL 文件加载到脚本中的真实示例。
\n
Add-Type -Path/ -LiteralPath,如您的代码所示,就是这样做的:
它加载指定的 .NET 程序集并使其公共类型在调用会话中可用,就像类似的using assembly语句一样。
但是,由于您正在使用class定义\n尝试从通过类型文字(例如)从同一脚本文件加载的程序集中引用类型,因此类定义失败:[WinSCP.Protocol]
在脚本文件解析时,所有类型都被定义引用class为类型文字(例如[WinSCP.Protocol]) - 无论是作为属性类型,在方法体中,还是作为要实现的基类/接口(尽管在后一种情况下,类型文字没有外壳;例如) -\n必须已加载到会话中,从 PowerShell 7.3.6 开始。[1][...]class Foo : WinSCP.Protocol { ... }
using assembly声明的这一违反直觉的要求已于 2017 年获得批准,但截至撰写本文时尚未实施:请参阅GitHub 问题 #3641。解决方法:
\n这个答案提供了两种解决方案:
\nInvoke-Expression的解决方案。这个答案提供了一个简单的两个脚本解决方案:
\nclass并不总是需要解决方法,即如果您避免使用类型文字,例如[WinSCP.Protocol]
对于[WinSCP.SessionOptions],您已经通过使用而不是更现代的 (PSv5+) 来做到这一点New-Object WinSCP.SessionOptions[WinSCP.SessionOptions]::new()
[WinSCP.Protocol]::Sftp您还可以通过简单地使用字符串来避免枚举值-\'Sftp\'相反 - 至少对于显示的代码片段来说这可以解决您的问题;这是一个简化的示例:
class Foo {\n # Note: Do NOT use [WinSCP.SessionOptions] here.\n [object] $sessionOptions \n [void] CreateSession() {\n # Load WinSCP .NET assembly\n Add-Type -LiteralPath (Join-Path $PSScriptRoot "\\winscp\\WinSCPnet.dll")\n # Set up session options\n # Note the use of *string* \'Sftp\' in lieu of [WinSCP.Protocol]::Sftp\n $this.sessionOptions = New-Object WinSCP.SessionOptions -Property @{\n Protocol = \'Sftp\' \n }\n }\n}\nRun Code Online (Sandbox Code Playgroud)\n现在您可以[Foo]像平常一样实例化 - 使用New-Object Foo或 ,最好是使用[Foo]::new()(一旦[Foo]成功定义了它本身,就可以通过类型文字、外部定义来引用它)。 class
[1] 类是 PowerShell 语言中相对较晚的补充,不幸的是,仍然有许多问题需要解决 - 请参阅GitHub 问题 #6652中的待处理问题列表。但请注意,与 C# 类等程序的功能对等从来都不是目标。\n
\n| 归档时间: |
|
| 查看次数: |
3966 次 |
| 最近记录: |