【问题标题】:How to use interfaces in Powershell defined via Add-Type?如何使用通过 Add-Type 定义的 Powershell 中的接口?
【发布时间】:2019-10-07 22:36:54
【问题描述】:

我开发了一个 PowerShell 模块,该模块依赖 .NET 程序集进行某些操作。
我将此模块重构为不需要该程序集,并注意到一些奇怪的行为,这最终阻止了我删除该类:

Add-Type -TypeDefinition "public interface ICanTalk { string talk(); }" -Language CSharp

class Talker : ICanTalk {
    [string] talk() { return "Well hello there"; }
}

如果您以交互方式运行此命令,它将成功。 但是一旦我在 ISE 中或从 psm1 文件中运行它“en-bloque”,它就会抛出一个错误,指出它找不到在 Add-Type 调用中定义的接口。

我可以在 Windows-PowerShell 和 PowerShell Core (6.0.2) 中重现该问题

不同行为的原因是什么?我该如何解决?

【问题讨论】:

  • 不要相信 ISE。
  • 您可能是对的,但该示例是问题的最小再现,它也适用于通过 ipmo 加载的 psm1 文件。
  • 感谢您的澄清。我可以说您的测试用例也发生在 6.0.3 中。感觉Add-Type 命令没有被执行。
  • 也许类在其他任何东西有机会执行之前就被解析了?

标签: powershell


【解决方案1】:

补充your own answer

PowerShell classenum 定义在执行开始之前进行解析,并且任何类型在这些定义中引用 strong> 必须是:

  • 加载到当前会话事先

  • [仅部分实现自 Windows PowerShell v5.1 / PowerShell Core 6.1.0]
    通过 using module / @987654328 加载@声明在最 文件顶部。

    • using module 已经有效,但前提是引用的类型本身 PowerShell class / enum 定义。

    • 目前,尚未检测到从程序集加载的类型——无论是通过包含使用using moduleusing assembly 导入的程序集的模块来直接加载程序集。

      • 请参阅以下 GitHub 问题:
        • #3461 (using module) 和 #2074 (using assembly)
        • #6652 - 一个跟踪所有类相关问题的元问题。

同时,解决方法预先通过单独的脚本加载引用的类型,方法是使用模块清单的NestedModules 条目 .

  • 注意:ScriptsToProcess 条目也可以,但它引用的脚本是点源代码(加载到当前范围)调用者,而不是封闭模块。
    对于来自编译代码的类型(包括带有Add-Type 的临时编译代码),这也可以,因为这些类型总是在会话全局范围内可用,但使用NestedModules 在概念上更简洁,因为它在封闭的模块的范围内提供点源脚本

【讨论】:

    【解决方案2】:

    显然 PowerShell 会在执行代码之前读取文件并处理类定义。

    要解决这个问题,Add-Type 需要放入一个自己的脚本文件中,该文件在模块加载之前运行(或者在 ISE 中,只需在运行类定义之前运行代码)。

    这可以通过使用 PSD1 文件中的 ScriptsToProcess 来完成。

    感谢@TheIncorrigible1 让我走上正轨。

    【讨论】:

      【解决方案3】:

      为什么不在一个单独的文件中定义 C# 中的所有类,而不是将其添加为 添加类型-path MyClasses.cs 这样它就可以与旧的 PS 版本一起使用

      【讨论】:

      • 该模块需要Core 6.0或安装了NET 472的桌面版,所以支持旧版本没有用。我也希望它尽可能地成为 PS
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-08-05
      • 2010-10-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多