我在 Windows 7 机器上使用 PowerShell 5.1 并尝试从 PowerShell 类内部引用 .NET 程序集中的类型,并且收到“无法找到类型”错误。
我的“主”程序是 FooProg.ps1,我在其中创建 FooMod 类的新实例
#Requires -Version 5.1
using module .\FooMod\FooMod.psm1
[FooMod]::new() | out-null
FooMod 类位于 FooMod 子文件夹中的 PowerShell 模块 (FooMod.psm1) 中
#Requires -Version 5.1
using assembly .\Foo.dll
using namespace Foo
class FooMod {
FooMod() {
Write-Host "Start - Assembly access"
[Bar] $bar = [Bar]::new()
Write-Host $bar.Name
Write-Host $bar.Greeting()
Write-Host "Finish - Assembly access"
}
}
我的 Foo.dll 是从以下 Bar.cs 构建的,并且与模块文件 (FooMod.psm1) 和模块 list 文件 (FooMod.psd1) 一起位于 FooMod 子文件夹中
namespace Foo {
public class Bar {
public string Name;
public Bar(string name) => this.Name = name;
public Bar() : this("Bar") {
}
public string Greeting() {
return System.String.Format("Hello! My name is {0}", Name);
}
}
}
我在名为 FooMod.psd1 的 FooMod 子文件夹中还有一个模块 list ,其中包含这些相关条目
RootModule = 'FooMod.psm1'
RequiredAssemblies = 'Foo.dll'
还有什么我想念的吗?在类外使用程序集可以正常工作,实例化 PowerShell 类(不引用程序集/外部类型)可以正常工作 - 但是结合 PowerShell 类和程序集类型是不行的!
最佳答案
弄清楚了!原来在主脚本FooProg.ps1中,using语句需要引用Module Manifest和不是 模块脚本。
所以而不是使用
#Requires -Version 5.1
using module .\FooMod\FooMod.psm1
[FooMod]::new() | out-null
我把它改成
#Requires -Version 5.1
using module .\FooMod\FooManifest.psd1
[FooModule]::new() | out-null
因此,我还从 重命名了我的模块 list 文件。 .\FooMod\FooMod.psd1 至 .\FooMod\FooManifest.psd1
此外,在模块 list 文件中,我更改了条目 RootModule = 'FooMod.psm1' 至 RootModule = 'FooModule.psm1' .这不是必需的更改,但有助于理解不同文件的结构。
这显然导致将模块脚本从 重命名。 FooMod.psm1 至 FooModule.psm1 以及从 更改模块脚本中的类名美食模组 至食品模块 .同样不是必需的更改,但它与将类命名为与包含它们的文件名相同的名称是一致的。
整个练习让我相信在主脚本中命名的模块 list 文件需要首先处理,以便在 中命名的程序集所需组件 在 中命名的模块之前加载根模块 被解析。这使得外部 .NET 程序集中的类型在解析模块时可用,并防止出现“无法找到类型”错误。
现在配备了新的 FooModule.psm1 文件
#Requires -Version 5.1
using assembly .\Foo.dll
using namespace Foo
class FooModule {
FooModule() {
Write-Host "Start - Assembly access"
Write-Host
[Bar] $bar1 = [Bar]::new("Romeo")
Write-Host $bar1.Name
Write-Host $bar1.Greeting()
Write-Host
[Bar] $bar2 = [Bar]::new("Juliet")
Write-Host $bar2.Name
Write-Host $bar2.Greeting()
Write-Host
Write-Host "Finish - Assembly access"
}
}
我得到的输出如下
Start - Assembly access
Romeo
Hello! My name is Romeo
Juliet
Hello! My name is Juliet
Finish - Assembly access
关键是使用模块 list ,正确设置RequiredAssemblies 键,并在主脚本中引用模块 list 而不是模块脚本本身。
关于.net - 在 PS 类中引用程序集会导致 "Unable to find type"错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46287307/