2014-09-08 4 views
5

Sto facendo qualcosa di stupido qui?PowerShell non può utilizzare il tipo enum corrispondente?

specifico che una funzione accetta un particolare tipo enum come argomento:

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

Il tipo è sicuramente portata poiché posso accedere a istanze di essa (e importato il gruppo manualmente):

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

Poi quando provo per passare la funzione un'istanza di detto enum, esso errori fuori:

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 

E 'molto felice costringere una stringa, però:

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

Cosa sta succedendo?

(messaggi di errore PowerShell sono così disordinato cercando. = /)

risposta

6

Si esegue in una piccola per quanto riguarda le modalità di analisi. Si può mettere parentesi intorno all'argomento e funzionerà:

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

In alternativa, le conversioni da stringa a ENUM accadere naturalmente, così si potrebbe scrivere:

test Stopped 

Qui ci sono un paio di buoni collegamenti che discutono parsing modalità:

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

A quanto pare, PowerShell pensa che io mando una stringa, piuttosto che un oggetto enum. È possibile ottenere lo stesso messaggio di errore se si cita il nome completo:

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 

Mettere l'enum tra parentesi per forzare PowerShell per valutare lo fa prima il trucco:

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

È possibile passare un valore di enumerazione come stri ng ma non si passa il typename come parte dell'argomento, ad es. questo funziona bene:

PS> test Stopped 
Stopped System.ServiceProcess.ServiceControllerStatus 

Detto questo, quando sto chiamando i metodi .NET preferisco usare il valore enum completo invece di una stringa. Questo perché i metodi .NET tendono ad avere sovraccarichi multipli e quelli che prendono le stringhe possono confondere PowerShell quando viene a scegliere il sovraccarico corretto.

0

Non si specifica correttamente il parametro $x. Deve essere racchiuso in un'espressione param().

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

più si può omettere la parte System. di qualsiasi nome tipo.

+0

Abbastanza sicuro che sia davvero un vecchio consiglio dai giorni PS1 o qualcosa del genere ... Come si vede nelle altre risposte, la sintassi nella domanda funziona come previsto. È la chiamata che sta avendo problemi di analisi. – jpmc26