2014-09-08 12 views
5

Mache ich hier etwas Dummes?PowerShell kann den passenden Aufzählungstyp nicht verwenden?

ich angeben, dass eine Funktion eine bestimmte Aufzählungstyp als Argument:

PS> add-type -AssemblyName System.ServiceProcess 
PS> function test([System.ServiceProcess.ServiceControllerStatus]$x) { Write-host $x $x.gettype() } 

Die Art ist definitiv in Umfang, da ich Instanzen zugreifen kann (und ich importierte die Baugruppe manuell):

PS> [System.ServiceProcess.ServiceControllerStatus]::Stopped 
Stopped 

Dann, wenn ich versuche, die Funktion eine Instanz des enum zu passieren, es Fehler aus:

PS> test [System.ServiceProcess.ServiceControllerStatus]::Stopped 
test : Cannot process argument transformation on parameter 'x'. Cannot convert value 
"[System.ServiceProcess.ServiceControllerStatus]::Stopped" to type "System.ServiceProcess.ServiceControllerStatus". 
Error: "Unable to match the identifier name [System.ServiceProcess.ServiceControllerStatus]::Stopped to a valid 
enumerator name. Specify one of the following enumerator names and try again: Stopped, StartPending, StopPending, 
Running, ContinuePending, PausePending, Paused" 
At line:1 char:6 
+ test [System.ServiceProcess.ServiceControllerStatus]::Stopped 
+  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
    + CategoryInfo   : InvalidData: (:) [test], ParameterBindingArgumentTransformationException 
    + FullyQualifiedErrorId : ParameterArgumentTransformationError,test 

Es ist ganz glücklich einen String Nötigung, aber:

PS> test 'Stopped' 
Stopped System.ServiceProcess.ServiceControllerStatus 

Was ist los?

(Powershell-Fehlermeldungen sind so chaotisch suchen. = /)

Antwort

6

Sie sind in einem kleinen Lauf gotcha in Bezug auf Parsing-Modi. Sie können Pars um das Argument setzen und es wird funktionieren:

test ([System.ServiceProcess.ServiceControllerStatus]::Stopped) 

Alternativ Konvertierungen von String Enum natürlich passieren, so dass Sie schreiben können:

test Stopped 

Hier ein paar gute Links, die Parsen diskutieren Modi:

http://technet.microsoft.com/en-us/library/hh847892.aspx http://rkeithhill.wordpress.com/2007/11/24/effective-powershell-item-10-understanding-powershell-parsing-modes/

0

Offenbar Powershell denkt, dass ich es eine Zeichenfolge schicke, anstatt ein ENUM-Objekt. Sie erhalten die gleiche Fehlermeldung, wenn Sie den vollständig qualifizierten Namen zitieren:

PS> test '[System.ServiceProcess.ServiceControllerStatus]::Stopped' 
test : Cannot process argument transformation on parameter 'x'. Cannot convert value 
"[System.ServiceProcess.ServiceControllerStatus]::Stopped" to type "System.ServiceProcess.ServiceControllerStatus". 
Error: "Unable to match the identifier name [System.ServiceProcess.ServiceControllerStatus]::Stopped to a valid 
enumerator name. Specify one of the following enumerator names and try again: Stopped, StartPending, StopPending, 
Running, ContinuePending, PausePending, Paused" 
At line:1 char:6 
+ test '[System.ServiceProcess.ServiceControllerStatus]::Stopped' 
+  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
    + CategoryInfo   : InvalidData: (:) [test], ParameterBindingArgumentTransformationException 
    + FullyQualifiedErrorId : ParameterArgumentTransformationError,test 

die Enum in Klammern Putting Powershell zu zwingen, es zuerst zu bewerten funktioniert der Trick:

PS> test ([System.ServiceProcess.ServiceControllerStatus]::Stopped) 
Stopped System.ServiceProcess.ServiceControllerStatus 
2

Sie können eine eNUM-Wert als stri geben ng, aber Sie übergeben den Typenname nicht als Teil des Arguments, z. dies funktioniert gut:

PS> test Stopped 
Stopped System.ServiceProcess.ServiceControllerStatus 

Das heißt, wenn ich .NET-Methoden bin Aufruf Ich ziehe den vollständig qualifizierten Enum-Wert anstelle einer Zeichenfolge zu verwenden. Das liegt daran, dass .NET-Methoden häufig mehrere Überladungen aufweisen und solche, die Zeichenfolgen verwenden, die PowerShell bei der Auswahl der richtigen Überladung verwirren können.

0

Sie geben den Parameter $x nicht korrekt an. Es muss in einen Ausdruck param() ausgedrückt werden.

function test 
{ 
    param(
     [ServiceProcess.ServiceControllerStatus] 
     $x 
    ) 
    Write-host $x $x.gettype() 
} 

plus können Sie den System. Teil eines beliebigen Typs Namen weglassen.

+0

Ziemlich sicher, das ist wirklich alte Ratschläge zurück von den PS1 Tagen oder etwas ... Wie in den anderen Antworten gesehen, funktioniert die Syntax in der Frage wie erwartet. Es ist der Aufruf, der einige Parsing-Probleme hat. – jpmc26

Verwandte Themen