我在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构建的,并且与Module文件(FooMod.psm1)和Module Manifest文件(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子文件夹中有一个Module Manifest,其中包含这些相关条目
RootModule = 'FooMod.psm1'
RequiredAssemblies = 'Foo.dll'
还有什么我想念的吗?使用类外部的程序集工作正常,实例化PowerShell类(不引用程序集/外部类型)工作正常 - 但组合PowerShell类和程序集类型是不行的!
答案 0 :(得分:1)
想出来!事实证明,在主脚本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
因此,我还将我的Module Manifest文件从。\ FooMod \ FooMod.psd1 重命名为。\ FooMod \ FooManifest.psd1
此外,在Module Manifest文件中,我将条目 RootModule =&#39; FooMod.psm1&#39; 更改为 RootModule =&#39; FooModule.psm1&#39; < / strong>即可。这不是必需的更改,但有助于理解不同文件的结构。
这显然导致将模块脚本从 FooMod.psm1 重命名为 FooModule.psm1 ,并且还从 FooMod <更改模块脚本中的类名称/ strong>到 FooModule 。同样不是必需的更改,但它与命名类一致,与包含它们的文件名相同。
整个练习让我相信需要首先处理主脚本中命名的Module Manifest文件,以便在 RequiredAssemblies 中命名的程序集在<解析strong> RootModule 。这使得外部.NET程序集中的类型在解析模块时可用,并防止&#34;无法找到类型&#34;错误。
现在配备了新的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本身。