Utilizzo dell'attività InvokePowerShell
Le informazioni contenute in questo argomento sono valide per Windows Workflow Foundation 4.
Nell'esempio InvokePowerShell viene illustrato come richiamare i comandi di Windows PowerShell utilizzando l'attività InvokePowerShell
.
Dimostrazione
Semplice innovazione dei comandi di Windows PowerShell.
Recupero di valori dalla pipeline di output di Windows PowerShell e relativa archiviazione nelle variabili del flusso di lavoro.
Passaggio di dati in Windows PowerShell come pipeline di input per un comando di esecuzione.
Nota: |
---|
È possibile che gli esempi siano già installati nel computer. Verificare la directory seguente (impostazione predefinita) prima di continuare.
<UnitàInstallazione>:\WF_WCF_Samples
Se questa directory non esiste, andare alla sezione relativa agli esempi di Windows Communication Foundation (WCF) e Windows Workflow Foundation (WF) per .NET Framework 4 per scaricare tutti gli esempi Windows Communication Foundation (WCF) e WF. Questo esempio si trova nella directory seguente.
<UnitàInstallazione>:\WF_WCF_Samples\WF\Scenario\ActivityLibrary\PowerShell
|
Discussione
In questo esempio sono contenuti i tre progetti seguenti.
Nome progetto | Descrizione | File principali |
---|---|---|
CodedClient |
Applicazione client di esempio che utilizza l'attività PowerShell. |
|
DesignerClient |
Set di attività personalizzate che contengono l'attività personalizzata |
|
PowerShell |
Attività |
File di attività
File delle finestre di progettazione:
|
I progetti client vengono discussi per primi, poiché è più semplice capire la funzionalità interna dell'attività PowerShell una volta capito il relativo utilizzo.
Utilizzo dell'esempio
Nelle sezioni seguenti viene descritto come utilizzare i tre progetti dell'esempio.
Utilizzo del progetto CodedClient
Il client di esempio crea a livello di codice un'attività Sequence che contiene esempi di diversi metodi di utilizzo dell'attività InvokePowerShell
. La prima chiamata avvia il Blocco note.
new InvokePowerShell()
{
CommandText = "notepad"
},
La seconda chiamata ottiene un elenco dei processi in esecuzione nel computer locale.
new InvokePowerShell<Process>()
{
CommandText = "Get-Process",
Output = processes1,
},
Output
è la variabile utilizzata per archiviare l'output del comando.
La chiamata successiva dimostra come eseguire una fase di post-elaborazione in ogni singolo output della chiamata di PowerShell. L'oggetto InitializationAction
viene impostato sulla funzione che restituisce una rappresentazione di stringa per ogni processo. La raccolta di queste stringhe viene restituita nella variabile Output
dall'attività InvokePowerShell<string>
.
Le chiamate InvokePowerShell
successive dimostrano il passaggio di dati nell'attività e la restituzione di output ed errori.
Utilizzo del progetto DesignerClient
Il progetto DesignerClient è costituito da un set di attività personalizzate, di cui gran parte è stata compilata con l'attività InvokePowerShell
. La maggior parte delle attività chiama la versione non generica dell'attività InvokePowerShell
e non prevede un valore restituito. Le altre attività utilizzano la versione generica dell'attività InvokePowerShell
e l'argomento InitializationAction
per elaborare i risultati in un secondo momento.
Utilizzo del progetto PowerShell
L'azione principale dell'attività si verifica nella classe ExecutePowerShell
. Poiché l'esecuzione dei comandi di PowerShell non deve bloccare il thread del flusso di lavoro principale, l'attività viene creata in modo da essere un'attività asincrona ereditando dalla classe AsyncCodeActivity.
Il metodo BeginExecute viene chiamato dall'esecuzione del flusso di lavoro per iniziare l'esecuzione dell'attività. Inizia chiamando le API di PowerShell per creare una pipeline di PowerShell.
runspace = RunspaceFactory.CreateRunspace();
runspace.Open();
pipeline = runspace.CreatePipeline();
Successivamente crea un comando di PowerShell e lo popola con parametri e variabili.
Command cmd = new Command(this.CommandText, this.IsScript);
// loop over parameters and run: cmd.Parameters.Add(...)
// loop over variables and run: runspace.SessionStateProxy.SetVariable(...)
pipeline.Commands.Add(cmd);
A questo punto, gli input inoltrati tramite pipe vengono inviati anche alla pipeline. Infine, la pipeline viene sottoposta a wrapping in un oggetto PipelineInvokerAsyncResult
e restituita. L'oggetto PipelineInvokerAsyncResult
registra un listener e richiama la pipeline.
pipeline.InvokeAsync();
Al termine dell'esecuzione, gli output e gli errori vengono archiviati all'interno dello stesso oggetto PipelineInvokerAsyncResult
e il controllo viene restituito all'esecuzione del flusso di lavoro chiamando il metodo di callback passato originariamente al metodo BeginExecute.
Alla fine dell'esecuzione del metodo, l'esecuzione del flusso di lavoro chiama il metodo EndExecute dell'attività.
La classe InvokePowerShell
esegue il wrapping della classe ExecutePowerShellCommand
e crea due versioni dell'attività: una generica e una non generica. La versione non generica restituisce direttamente l'output dell'esecuzione di PowerShell, mentre la versione generica trasforma i singoli risultati nel tipo generico.
La versione generica dell'attività viene implementata come un flusso di lavoro sequenziale che chiama l'oggetto ExecutePowerShellCommand
ed elabora i risultati in un secondo momento. Per ogni elemento nella raccolta di risultati, la fase di post-elaborazione chiama l'oggetto InitializationAction
se impostato. In caso contrario, esegue un semplice cast.
new ForEach<PSObject>
{
Values = psObjects,
Body = new ActivityAction<PSObject>
{
Argument = psObject,
Handler = new Sequence
{
Activities =
{
new If
{
Condition = // Is InitializationAction set?
Then = new InvokeFunc<PSObject, TResult>
{
Argument = psObject,
Result = outputObject,
Func = this.InitializationAction
},
Else = new Assign<TResult>
{
To = outputObject,
Value = new InArgument<TResult>(ctx => (TResult) psObject.Get(ctx).BaseObject),
}
},
new AddToCollection<TResult>
{
Collection = outputObjects,
Item = outputObject
},
}
}
}
},
Per ognuna delle due attività InvokePowerShell
(generica e non generica), è stata creata una finestra di progettazione. InvokePowerShellDesigner.xaml e il file con estensione cs associato definiscono l'aspetto in Progettazione flussi di lavoro per la versione non generica dell'attività InvokePowerShell
. In InvokePowerShellDesigner.xaml, viene utilizzato un oggetto DockPanel per rappresentare l'interfaccia grafica.
<DockPanel x:Uid="DockPanel_1" LastChildFill="True">
<TextBlock x:Uid="TextBlock_1" Text="CommandText" />
<TextBox x:Uid="TextBox_1" Text="{Binding Path=ModelItem.CommandText, Mode=TwoWay}"
TextWrapping="WrapWithOverflow" AcceptsReturn="True" MinLines="4" MaxLines="4"
Background="{x:Null}" Margin="3" />
</DockPanel>
Si noti che la proprietà Text
della casella di testo è un'associazione bidirezionale che assicura che il valore della proprietà CommandText
dell'attività sia equivalente al valore inserito nella finestra di progettazione.
GenericInvokePowerShellDesigner.xaml e il file con estensione cs associato definiscono l'interfaccia grafica per l'attività InvokePowerShell
generica. La finestra di progettazione è leggermente più complessa perché consente agli utenti di impostare un oggetto InitializationAction
. L'elemento principale è l'utilizzo dell'oggetto WorkflowItemPresenter per consentire il trascinamento delle attività figlio nell'area di progettazione di InvokePowerShell
.
<sap:WorkflowItemPresenter x:Uid="sap:WorkflowItemPresenter_1" Margin="0,10,0,10"
HintText="Drop Activities Here"
AllowedItemType="{x:Type sa:Activity}"
Item="{Binding Path=ModelItem.InitializationAction.Handler, Mode=TwoWay}"
Grid.Row="1" Grid.Column="1" />
La personalizzazione della finestra di progettazione non termina con i file con estensione xaml che definiscono l'aspetto dell'attività nell'area di disegno della progettazione. Anche le finestre di dialogo utilizzate per visualizzare i parametri dell'attività possono essere personalizzate. Questi parametri e le variabili PowerShell influiscono sul comportamento dei comandi di PowerShell. L'attività li espone come tipi Dictionary. ArgumentDictionaryEditor.cs, PropertyEditorResources.xaml e PropertyEditorResources.cs definiscono la finestra di dialogo che consente di modificare questi tipi.
Per impostare, compilare ed eseguire l'esempio
È necessario installare Windows PowerShell per eseguire questo esempio. Windows PowerShell può essere installato da questo percorso: Windows PowerShell.
Per eseguire il progetto CodedClient
Aprire PowerShell.sln tramite Visual Studio 2010.
Fare clic con il pulsante destro del mouse sulla soluzione e compilarla.
Fare clic con il pulsante destro del mouse sul progetto CodedClient e selezionare Imposta come progetto di avvio.
Premere CTRL+F5 per eseguire l'applicazione.
Per eseguire il progetto DesignerClient
Aprire PowerShell.sln tramite Visual Studio 2010.
Fare clic con il pulsante destro del mouse sulla soluzione e compilarla.
Fare clic con il pulsante destro del mouse sul progetto DesignerClient e selezionare Imposta come progetto di avvio.
Premere CTRL+F5 per eseguire l'applicazione.
Problemi noti
Se si fa riferimento all'assembly o al progetto di attività
InvokePowerShell
da un altro progetto si verifica un errore di compilazione, pertanto potrebbe essere necessario aggiungere manualmente l'elemento<SpecificVersion>True</SpecificVersion>
al file con estensione csproj del nuovo progetto sotto la riga che fa riferimento aInvokePowerShell
.Se Windows PowerShell non è installato, il seguente messaggio di errore viene visualizzato in Visual Studio non appena si aggiunge un'attività
InvokePowerShell
in un flusso di lavoro:Progettazione flussi di lavoro ha riscontrato problemi con il documento. Impossibile caricare il file o l'assembly 'System.Management.Automation'... o una delle sue dipendenze. Il sistema non riesce a trovare il file specificato.
In Windows PowerShell 2.0, la chiamata a livello di codice di
$input.MoveNext()
non viene eseguita correttamente e gli script che utilizzano$input.MoveNext()
generano errori e risultati imprevisti. Per risolvere questo problema, utilizzare il verbo PowerShellforeach
anziché chiamareMoveNext()
quando si scorre una matrice.
Nota: |
---|
È possibile che gli esempi siano già installati nel computer. Verificare la directory seguente (impostazione predefinita) prima di continuare.
<UnitàInstallazione>:\WF_WCF_Samples
Se questa directory non esiste, andare alla sezione relativa agli esempi di Windows Communication Foundation (WCF) e Windows Workflow Foundation (WF) per .NET Framework 4 per scaricare tutti gli esempi Windows Communication Foundation (WCF) e WF. Questo esempio si trova nella directory seguente.
<UnitàInstallazione>:\WF_WCF_Samples\WF\Scenario\ActivityLibrary\PowerShell
|