How to use interfaces in Powershell defined via Add-Type?

前端 未结 3 1590
南笙
南笙 2021-01-16 09:22

I developed a PowerShell module that relied on a .NET Assembly for some operations.
I refactored this module to not need that Assembly and noticed some strange behavior,

相关标签:
3条回答
  • 2021-01-16 10:14

    To complement your own answer:

    PowerShell class and enum definitions are parsed before execution begins and any types referenced in such definitions must either be:

    • loaded into the current the session beforehand.

    • [only partially implemented as of Windows PowerShell v5.1 / PowerShell Core 6.1.0]
      loaded via a using module / using assembly statement at the very top of the file.

      • using module already works, but only if the referenced types are themselves PowerShell class / enum definitions.

      • Currently, types loaded from assemblies - whether via a module containing assemblies imported with using module or using assembly to directly load an assembly - aren't yet detected.

        • See the following GitHub issues:
          • #3461 (using module) and #2074 (using assembly)
          • #6652 - a meta issue tracking all class-related issues.

    The workaround in the meantime is to load the referenced types via a separate script beforehand, by using the module manifest's NestedModules entry.

    • Note: The ScriptsToProcess entry would work too, but the scripts it references are dot-sourced in (loaded into the current scope of) the caller, not the enclosing module.
      With types from compiled code (including ad hoc-compiled code with Add-Type), that works too, because such types invariably become available session-globally, but it is conceptually cleaner to use NestedModules, because it dot-sources scripts in the enclosing module's scope
    0 讨论(0)
  • 2021-01-16 10:15

    Apparently PowerShell will read the file and handle class-definitions before executing the code.

    To solve this problem, the Add-Type needs to be put into an own script file, which is run before the module loads (or in ISE, just run the code before running the class definitions).

    This can be accomplished by using ScriptsToProcess from the PSD1 file.

    Kudos to @TheIncorrigible1 for putting me on the track.

    0 讨论(0)
  • 2021-01-16 10:23

    Why not defining all classes in C# in a separate file, than add it as Add-Type -path MyClasses.cs This way it will work with older PS versions

    0 讨论(0)
提交回复
热议问题