Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
978 views
in Technique[技术] by (71.8m points)

powershell - How do I conditionally add a class with Add-Type -TypeDefinition if it isn't added already?

Consider the following PowerShell snippet:

$csharpString = @"
using System;

public sealed class MyClass
{
    public MyClass() { }
    public override string ToString() {
        return "This is my class. There are many others " +
            "like it, but this one is mine.";
    }
}
"@
Add-Type -TypeDefinition $csharpString;
$myObject = New-Object MyClass
Write-Host $myObject.ToString();

If I run it more than once in the same AppDomain (e.g. run the script twice in powershell.exe or powershell_ise.exe) I get the following error:

Add-Type : Cannot add type. The type name 'MyClass' already exists.
At line:13 char:1
+ Add-Type -TypeDefinition $csharpString;
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (MyClass:String) [Add-Type],
 Exception
    + FullyQualifiedErrorId :
 TYPE_ALREADY_EXISTS,Microsoft.PowerShell.Commands.AddTypeCommand

How do I wrap the call to Add-Type -TypeDefinition so that its only called once?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

This technique works well for me:

if (-not ([System.Management.Automation.PSTypeName]'MyClass').Type)
{
    Add-Type -TypeDefinition 'public class MyClass { }'
}
  • The type name can be enclosed in quotes 'MyClass', square brackets [MyClass], or both '[MyClass]' (v3+ only).
  • The type name lookup is not case-sensitive.
  • You must use the full name of the type, unless it is part of the System namespace (e.g. [System.DateTime] can be looked up via 'DateTime', but [System.Reflection.Assembly] cannot be looked up via 'Assembly').
  • I've only tested this in Win8.1; PowerShell v2, v3, v4.

Internally, the PSTypeName class calls the LanguagePrimitives.ConvertStringToType() method which handles the heavy lifting. It caches the lookup string when successful, so additional lookups are faster.

I have not confirmed whether or not any exceptions are thrown internally as mentioned by x0n and Justin D.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...