Verwenden der InvokePowerShell-Aktivität
Dieses Thema gilt für Windows Workflow Foundation 4.
Im InvokePowerShell-Beispiel wird veranschaulicht, wie Windows PowerShell-Befehle mit der InvokePowerShell
-Aktivität aufgerufen werden.
Veranschaulicht
Einfache Innovation von Windows PowerShell-Befehlen.
Rufen Sie Werte aus der Windows PowerShell-Ausgabepipeline ab, und speichern Sie diese in Workflowvariablen.
Übergeben Sie Daten an Windows PowerShell als Eingabepipeline für einen Ausführungsbefehl.
Hinweis: |
---|
Die Beispiele sind möglicherweise bereits auf dem Computer installiert. Überprüfen Sie das folgende (standardmäßige) Verzeichnis, bevor Sie fortfahren.
<Installationslaufwerk>:\WF_WCF_Samples
Wenn dieses Verzeichnis nicht vorhanden ist, rufen Sie Windows Communication Foundation (WCF) and Windows Workflow Foundation (WF) Samples for .NET Framework 4 auf, um alle Windows Communication Foundation (WCF)- und WF-Beispiele herunterzuladen. Dieses Beispiel befindet sich im folgenden Verzeichnis.
<Installationslaufwerk>:\WF_WCF_Samples\WF\Scenario\ActivityLibrary\PowerShell
|
Diskussion
Dieses Beispiel enthält die folgenden drei Projekte.
Projektname | Beschreibung | Hauptdateien |
---|---|---|
CodedClient |
Eine Beispielclientanwendung, die die PowerShell-Aktivität verwendet. |
|
DesignerClient |
Ein Satz benutzerdefinierter Aktivitäten, die die benutzerdefinierte Aktivität |
|
PowerShell |
Die |
Aktivitätsdateien
Designerdateien:
|
Die Clientprojekte werden zuerst erläutert, da es einfacher ist, die interne Funktionalität der PowerShell-Aktivität zu verstehen, nachdem ihre Verwendung verstanden wurde.
Verwenden dieses Beispiels
In den folgenden Abschnitten wird beschrieben, wie die drei Projekte im Beispiel verwendet werden.
Verwenden des codierten Clientprojekts
Der Beispielclient erstellt programmgesteuert eine Sequenzaktivität, die Beispiele für mehrere verschiedene Methoden für die Verwendung der InvokePowerShell
-Aktivität enthält. Mit dem ersten Aufruf wird der Editor gestartet.
new InvokePowerShell()
{
CommandText = "notepad"
},
Der zweite Aufruf ruft eine Liste der Prozesse ab, die auf dem lokalen Computer ausgeführt werden.
new InvokePowerShell<Process>()
{
CommandText = "Get-Process",
Output = processes1,
},
Output
ist die Variable, die zum Speichern der Ausgabe des Befehls verwendet wird.
Der nächste Aufruf veranschaulicht, wie ein Nachverarbeitungsschritt für jede einzelne Ausgabe des PowerShell-Aufrufs ausgeführt wird. Für InitializationAction
wird die Funktion festgelegt, die eine Zeichenfolgendarstellung für die einzelnen Prozesse ausgibt. Die Auflistung dieser Zeichenfolgen wird in der Output
-Variablen von der InvokePowerShell<string>
-Aktivität zurückgegeben.
Die erfolgreichen InvokePowerShell
-Aufrufe veranschaulichen das Übergeben von Daten an die Aktivität und Abrufen von Ausgaben und Fehlern.
Verwenden des Designerclientprojekts
Das DesignerClient-Projekt besteht aus einem Satz benutzerdefinierter Aktivitäten, die fast alle die InvokePowerShell
-Aktivität enthalten. Die meisten der Aktivitäten rufen die nicht generische Version der InvokePowerShell
-Aktivität auf und erwarten keinen Rückgabewert. Andere Aktivitäten verwenden die generische Version der InvokePowerShell
-Aktivität und verwenden das InitializationAction
-Argument für die Nachverarbeitung der Ergebnisse.
Verwenden des PowerShell-Projekts
Die Hauptaktion der Aktivität findet in der ExecutePowerShell
-Klasse statt. Da die Ausführung von PowerShell-Befehlen den Hauptworkflowthread nicht blockieren sollte, wird die Aktivität als asynchrone Aktivität erstellt, indem sie von der AsyncCodeActivity-Klasse erbt.
Die BeginExecute-Methode wird von der Workflowlaufzeit aufgerufen, um mit der Ausführung der Aktivität zu beginnen. Sie beginnt mit dem Aufruf von PowerShell-APIs zum Erstellen einer PowerShell-Pipeline.
runspace = RunspaceFactory.CreateRunspace();
runspace.Open();
pipeline = runspace.CreatePipeline();
Anschließend erstellt sie einen PowerShell-Befehl und füllt ihn mit Parametern und Variablen.
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);
Die über die Pipeline übergebenen Eingaben werden an diesem Punkt ebenfalls an die Pipeline gesendet. Zum Schluss wird die Pipeline mit einem PipelineInvokerAsyncResult
-Objekt als Wrapper versehen und zurückgegeben. Das PipelineInvokerAsyncResult
-Objekt registriert einen Listener und ruft die Pipeline auf.
pipeline.InvokeAsync();
Nach dem Beenden der Ausführung werden die Ausgabe und Fehler in demselben PipelineInvokerAsyncResult
-Objekt gespeichert. Die Workflowlaufzeit erlangt wieder die Steuerung, indem die ursprünglich an BeginExecute übergebene Rückrufmethode aufgerufen wird.
Bei Ende der Methodenausführung ruft die Workflowlaufzeit die EndExecute-Methode der Aktivität auf.
Die InvokePowerShell
-Klasse fungiert als Wrapper der ExecutePowerShellCommand
-Klasse und erstellt zwei Versionen der Aktivität, eine generische Version und eine nicht generische Version. Die nicht generische Version gibt die Ausgabe der PowerShell-Ausführung direkt zurück, wohingegen die generische Version die einzelnen Ergebnisse in den generischen Typ transformiert.
Die generische Version der Aktivität wird als sequenzieller Workflow implementiert, der ExecutePowerShellCommand
aufruft und die Ergebnisse nachverarbeitet. Für jedes Element in der Ergebnisauflistung ruft der Nachverarbeitungsschritt InitializationAction
auf, wenn dies festgelegt ist. Andernfalls wird eine einfache Umwandlung ausgeführt.
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
},
}
}
}
},
Für jede der beiden InvokePowerShell
-Aktivitäten (generisch und nicht generisch) wurde ein Designer erstellt. InvokePowerShellDesigner.xaml und die entsprechende CS-Datei definieren die Darstellung in Workflow-Designer für die nicht generische Version der InvokePowerShell
-Aktivität. In InvokePowerShellDesigner.xaml wird ein DockPanel verwendet, um die grafische Schnittstelle darzustellen.
<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>
Beachten Sie, dass die Text
-Eigenschaft des Textfelds eine bidirektionale Bindung ist, die sicherstellt, dass der Wert der CommandText
-Eigenschaft der Aktivität dem im Designer eingegebenen Wert entspricht.
GenericInvokePowerShellDesigner.xaml und die entsprechende CS-Datei definieren die grafische Schnittstelle für die generische InvokePowerShell
-Aktivität. Der Designer ist etwas komplizierter, da er Benutzern ermöglicht, eine InitializationAction
festzulegen. Das Schlüsselelement ist die Verwendung von WorkflowItemPresenter, wodurch das Ziehen und Ablegen untergeordneter Aktivitäten in die InvokePowerShell
-Designer Oberfläche ermöglicht wird.
<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" />
Die Designeranpassung hört nicht mit den XAML-Dateien auf, die die Darstellung der Aktivität im Zeichenbereich definieren. Die Dialogfelder, die zum Anzeigen der Parameter der Aktivität verwendet werden, können ebenfalls angepasst werden. Diese Parameter und PowerShell-Variablen wirken sich auf das Verhalten von PowerShell-Befehlen aus. Die Aktivität macht sie als Dictionary-Typen verfügbar. Mit ArgumentDictionaryEditor.cs, PropertyEditorResources.xaml und PropertyEditorResources.cs wird das Dialogfeld definiert, das Ihnen ermöglicht, diese Typen zu bearbeiten.
So richten Sie das Beispiel ein, erstellen es und führen es aus
Sie müssen Windows PowerShell installieren, um dieses Beispiel ausführen zu können. Windows PowerShell kann von diesem Speicherort aus installiert werden: Windows PowerShell.
So führen Sie den kodierten Client aus
Öffnen Sie PowerShell.sln mit Visual Studio 2010.
Klicken Sie mit der rechten Maustaste auf die Projektmappe, und erstellen Sie sie.
Klicken Sie mit der rechten Maustaste auf das CodedClient-Projekt, und wählen Sie Als Startprojekt festlegen aus.
Drücken Sie STRG+F5, um die Anwendung auszuführen.
So führen Sie den Designerclient aus
Öffnen Sie PowerShell.sln mit Visual Studio 2010.
Klicken Sie mit der rechten Maustaste auf die Projektmappe, und erstellen Sie sie.
Klicken Sie mit der rechten Maustaste auf das DesignerClient-Projekt, und wählen Sie Als Startprojekt festlegen aus.
Drücken Sie STRG+F5, um die Anwendung auszuführen.
Bekannte Probleme
Wenn das Verweisen auf die
InvokePowerShell
-Aktivitätsassembly oder das Projekt von einem anderen Projekt zu einem Buildfehler führt, müssen Sie das<SpecificVersion>True</SpecificVersion>
-Element möglicherweise manuell der CSPROJ-Datei des neuen Projekts unter der Zeile, die aufInvokePowerShell
verweist, hinzufügen.Wenn Windows PowerShell nicht installiert ist, wird die folgende Fehlermeldung in Visual Studio angezeigt, sobald Sie einem Workflow eine
InvokePowerShell
-Aktivität hinzufügen:In Workflow Designer wurden Probleme mit dem Dokument erkannt. Die Datei oder Assembly 'System.Management.Automation' oder eine ihrer Abhängigkeit konnte nicht geladen werden. Das System konnte die angegebene Datei nicht finden.
In Windows PowerShell 2.0 schlägt das programmgesteuerte Aufrufen von
$input.MoveNext()
fehl, und Skripte, die$input.MoveNext()
verwenden, führen zu unbeabsichtigten Fehlern und Ergebnissen. Um dieses Problem zu vermeiden, ziehen Sie die Verwendung des PowerShell-Verbsforeach
in Betracht, anstatt bei der Wiederholung eines ArraysMoveNext()
aufzurufen.
Hinweis: |
---|
Die Beispiele sind möglicherweise bereits auf dem Computer installiert. Überprüfen Sie das folgende (standardmäßige) Verzeichnis, bevor Sie fortfahren.
<Installationslaufwerk>:\WF_WCF_Samples
Wenn dieses Verzeichnis nicht vorhanden ist, rufen Sie Windows Communication Foundation (WCF) and Windows Workflow Foundation (WF) Samples for .NET Framework 4 auf, um alle Windows Communication Foundation (WCF)- und WF-Beispiele herunterzuladen. Dieses Beispiel befindet sich im folgenden Verzeichnis.
<Installationslaufwerk>:\WF_WCF_Samples\WF\Scenario\ActivityLibrary\PowerShell
|