.net - 在 PS 类中引用程序集会导致 "Unable to find type"错误

标签 .net class powershell .net-assembly

我在 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/

相关文章:

asp.net - 调试中的.net 4 Web表单页面在本地中断

.net - 多生产者多消费者无锁(甚至无需等待)队列

c++ - C++ 类是否解决了函数覆盖问题?

php - 类型提示和默认参数值也是方法签名吗?

windows - powershell 中的批处理文件命令在不同的命令提示符下执行

c# - .NET 中 PowerShell 的引用是什么?

c# - 扔;据说不会重置堆栈跟踪,但在某些情况下会重置

.net - 更改了 .Net 4 中泛型方法的 LdToken 行为?

python - 在 python 中从 Base 普遍创建派生类

wpf - Powershell 包 uri 对象