How to use interfaces in Powershell defined via Add-Type?
Clash Royale CLAN TAG#URR8PPP
How to use interfaces in Powershell defined via Add-Type?
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, which blocks me from removing the class at last:
Add-Type -TypeDefinition "public interface ICanTalk string talk(); " -Language CSharp
class Talker : ICanTalk
[string] talk() return "Well hello there";
If you run this commands interactively, it will succeed.
But as soon as I run it "en-bloque" in ISE or from a psm1 file, it will throw an error, stating it cannot find the interface defined in the Add-Type
call.
Add-Type
I can reproduce the problem in both Windows-PowerShell and PowerShell Core (6.0.2)
What is the reason for the different behaviour and how can I tackle it?
Probably you are right, but the sample is a minimal reproduction of the problem and it also applies to psm1 files loaded via ipmo.
– TGlatzer
Aug 10 at 22:00
Thanks for the clarification. I can say your test case occurred for me as well in 6.0.3. It feels like the
Add-Type
command isn't being executed.– TheIncorrigible1
Aug 10 at 22:06
Add-Type
Perhaps classes are parsed before anything else has the chance to execute?
– TGlatzer
Aug 10 at 22:09
Possible duplicate of Using .Net Objects within a Powershell (V5) Class
– PetSerAl
Aug 11 at 1:56
2 Answers
2
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).
Add-Type
This can be accomplished by using ScriptsToProcess from the PSD1 file.
Kudos to @TheIncorrigible1 for putting me on the track.
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:
class
enum
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
using assembly
using module
already works, but only if the referenced types are themselves class
/ enum
definitions.
using module
class
enum
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.
using module
using assembly
using module
using assembly
The workaround in the meantime is to load the referenced types via a separate script beforehand, by using the module manifest's NestedModules
entry.
NestedModules
ScriptsToProcess
Add-Type
NestedModules
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.
Don't trust the ISE.
– TheIncorrigible1
Aug 10 at 21:58