我在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子文件夹FooMod.psd1中也有一个模块 list ,其中包含这些相关条目
RootModule = 'FooMod.psm1'
RequiredAssemblies = 'Foo.dll'
还有什么我想念的吗?在类外部使用程序集可以很好地工作,实例化PowerShell类(不引用程序集/外部类型)可以很好地工作-但是将PowerShell类和程序集类型结合起来是不行的!
最佳答案
弄清楚了!事实证明,在主脚本FooProg.ps1中,using语句需要引用Module Manifest,而 NOT 是模块脚本。
所以不要使用
#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 到了。
另外,在模块 list 文件中,我将条目 RootModule ='FooMod.psm1'更改为 RootModule ='FooModule.psm1'。这不是必需的更改,但有助于理解不同文件的结构。
这显然导致将模块脚本从 FooMod.psm1 重命名为 FooModule.psm1 ,并将模块脚本中的类名从 FooMod 更改为 FooModule 。同样,这不是必需的更改,但与命名类和包含它们的文件名相同,这是一致的。
整个练习使我相信主脚本中命名的Module Manifest文件需要首先处理,以便在解析 RootModule 中命名的模块之前,先加载 RequiredAssemblies 中命名的程序集。这样可以在解析模块时使外部.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
关键是使用Module Manifest,并正确设置RequiredAssemblies键,并在您的主脚本中引用Module Manifest,而不是Module Script本身。
关于.net - 在PS类内引用程序集会导致 “Unable to find type”错误,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/46287307/