Utilizzo dell'attività InvokePowerShellUsing the InvokePowerShell Activity

Nell'esempio InvokePowerShell viene illustrato come richiamare i comandi di Windows PowerShell usando l'attività InvokePowerShell.The InvokePowerShell sample demonstrates how to invoke Windows PowerShell commands using the InvokePowerShell activity.

DimostrazioneDemonstrates

  • Semplice innovazione dei comandi di Windows PowerShell.Simple innovation of Windows PowerShell commands.

  • Recupero di valori dalla pipeline di output di Windows PowerShell e relativa archiviazione nelle variabili del flusso di lavoro.Retrieve values from the Windows PowerShell output pipeline and store them in workflow variables.

  • Passaggio di dati in Windows PowerShell come pipeline di input per un comando di esecuzione.Pass data into windows PowerShell as input pipeline for an executing command.

Importante

È possibile che gli esempi siano già installati nel computer.The samples may already be installed on your machine. Verificare la directory seguente (impostazione predefinita) prima di continuare.Check for the following (default) directory before continuing.

<InstallDrive>:\WF_WCF_Samples

Se questa directory non esiste, andare al Windows Communication Foundation (WCF) e gli esempi di Windows Workflow Foundation (WF) per .NET Framework 4 per scaricare tutti i Windows Communication Foundation (WCF) e WFWF esempi.If this directory does not exist, go to Windows Communication Foundation (WCF) and Windows Workflow Foundation (WF) Samples for .NET Framework 4 to download all Windows Communication Foundation (WCF) and WFWF samples. Questo esempio si trova nella directory seguente.This sample is located in the following directory.

<InstallDrive>:\WF_WCF_Samples\WF\Scenario\ActivityLibrary\PowerShell

DiscussioneDiscussion

In questo esempio sono contenuti i tre progetti seguenti.This sample contains the following three projects.

Nome progettoProject Name DescrizioneDescription File principaliMain Files
CodedClientCodedClient Applicazione client di esempio che usa l'attività PowerShell.A sample client application that uses the PowerShell activity. - Program.cs: a livello di codice crea un flusso di lavoro basato su sequenze che chiama l'attività InvokePowerShell.- Program.cs: Programmatically creates a sequence-based workflow that calls the InvokePowerShell activity.
DesignerClientDesignerClient Set di attività personalizzate che contengono l'attività personalizzata InvokePowerShell e altre varie attività personalizzate, nonché un flusso di lavoro che le usa.A set of custom activities that contain the InvokePowerShell custom activity and other miscellaneous custom activities, and a workflow that uses them.
  • Attività:Activities:

    • PrintCollection.cs: attività di supporto che stampa tutti gli elementi in una raccolta nella console.PrintCollection.cs: A helper activity that prints all the items in a collection to the console.
    • ReadLine.cs: attività di supporto per la lettura di input dalla console.ReadLine.cs: A helper activity for reading input from the console.
  • File system:File System:

    • Copy. XAML: un'attività che consente di copiare un file.Copy.xaml: An activity that copies a file.
    • CreateFile. XAML: un'attività che crea un file.CreateFile.xaml: An activity that creates a file.
    • DeleteFile. XAML: un'attività che elimina un file.DeleteFile.xaml: An activity that deletes a file.
    • MakeDir. XAML: attività che crea una directory.MakeDir.xaml: An activity that creates a directory.
    • Move. XAML: un'attività che consente di spostare un file.Move.xaml: An activity that moves a file.
    • ReadFile: un'attività che legge un file e restituisce il relativo contenuto.ReadFile.xaml: An activity that reads a file and returns its contents.
    • TestPath: attività che verifica l'esistenza di un percorso.TestPath.xaml: An activity that tests for the existence of a path.
  • Processo:Process:

    • GetProcess: un'attività che ottiene un elenco dei processi in esecuzione.GetProcess.xaml: An activity that gets a list of running processes.
    • Stopprocess: un'attività che interrompe un processo specifico.StopProcess.xaml: An activity that stops a specific process.
  • Program.cs: chiama il flusso di lavoro Sequence1.Program.cs: Calls the Sequence1 workflow.
  • Sequence1.XAML: un flusso di lavoro basato su sequenze.Sequence1.xaml: A sequence-based workflow.
PowerShellPowerShell Attività InvokePowerShell e finestre di progettazione associate.The InvokePowerShell activity and its associated designers. File di attivitàActivity Files

- ExecutePowerShell.cs: logica di esecuzione principale dell'attività.- ExecutePowerShell.cs: The main execution logic of the activity.
- InvokePowerShell.cs: il wrapper per la logica di esecuzione principale, che contiene una versione generica (valore restituito) e una versione non generica (valore non restituito).- InvokePowerShell.cs: The wrapper around the main execution logic, which contains a generic (return value) version and a non-generic (non-return value) version. Si tratta dell'interfaccia pubblica per l'attività.This is the public interface for the activity.
- NoPersistZone.cs: questa attività impedisce la persistenza delle attività figlio.- NoPersistZone.cs: This activity prevents any child activities from persisting. Questa classe viene usata all'interno dell'implementazione dell'attività InvokePowerShell per evitare che l'attività venga resa persistente a metà esecuzione.This class is used within the InvokePowerShell activity implementation to prevent the activity from being persisted mid-execution.

File delle finestre di progettazione:Designer files:

1. ArgumentDictionaryEditor.cs: finestra di dialogo di Windows che consente all'utente di modificare gli argomenti del InvokePowerShell attività.1. ArgumentDictionaryEditor.cs: A Windows dialog that allows the user to edit the arguments of the InvokePowerShell activity.
2. Genericinvokepowershelldesigner e GenericInvokePowerShellDesigner.xaml.cs: definisce l'aspetto dell'oggetto generico InvokePowerShell attività Progettazione flussi di lavoroWorkflow Designer.2. GenericInvokePowerShellDesigner.xaml and GenericInvokePowerShellDesigner.xaml.cs: Defines the appearance of the generic InvokePowerShell activity in Progettazione flussi di lavoroWorkflow Designer.
3. Invokepowershelldesigner. XAML e InvokePowerShellDesigner.cs: definisce l'aspetto di non generica InvokePowerShell attività Progettazione flussi di lavoroWorkflow Designer.3. InvokePowerShellDesigner.xaml and InvokePowerShellDesigner.cs: Defines the appearance of the non-generic InvokePowerShell activity in Progettazione flussi di lavoroWorkflow Designer.

I progetti client vengono discussi per primi, poiché è più semplice capire la funzionalità interna dell'attività PowerShell una volta capito il relativo uso.The client projects are discussed first, as it is easier to understand the internal functionality of the PowerShell activity once its use is understood.

Utilizzo dell'esempioUsing This Sample

Nelle sezioni seguenti viene descritto come usare i tre progetti dell'esempio.The following sections describe how to use the three projects in the sample.

Utilizzo del progetto CodedClientUsing the Coded Client Project

Il client di esempio crea a livello di codice un'attività Sequence che contiene esempi di diversi metodi di utilizzo dell'attività InvokePowerShell.The sample client programmatically creates a sequence activity, which contains examples of several different methods of using the InvokePowerShell activity. La prima chiamata avvia il Blocco note.The first invocation launches Notepad.

new InvokePowerShell()  
{  
    CommandText = "notepad"  
},  

La seconda chiamata ottiene un elenco dei processi in esecuzione nel computer locale.The second invocation gets a list of the processes running on the local machine.

new InvokePowerShell<Process>()  
{  
    CommandText = "Get-Process",  
    Output = processes1,  
},  

Output è la variabile usata per archiviare l'output del comando.Output is the variable used to store the output of the command.

La chiamata successiva mostra come eseguire un passaggio della post-elaborazione in ogni singolo output della chiamata di PowerShell.The next call demonstrates how to run a post-processing step on each individual output of the PowerShell invocation. InitializationAction viene impostato sulla funzione che restituisce una rappresentazione in forma di stringa per ogni processo.InitializationAction is set to the function that outputs a string representation for each process. La raccolta di queste stringhe viene restituita nella variabile Output dall'attività InvokePowerShell<string>.The collection of these strings is returned in the Output variable by the InvokePowerShell<string> activity.

Le chiamate InvokePowerShell successive dimostrano il passaggio di dati nell'attività e la restituzione di output ed errori.The succeeding InvokePowerShell calls demonstrate passing data into the activity and getting outputs and errors out.

Utilizzo del progetto DesignerClientUsing the Designer Client Project

Il progetto DesignerClient è costituito da un set di attività personalizzate, di cui gran parte è stata compilata con l'attività InvokePowerShell.The DesignerClient project consists of a set of custom activities, almost all of which are built containing the InvokePowerShell activity. La maggior parte delle attività chiama la versione non generica dell'attività InvokePowerShell e non prevede un valore restituito.Most of the activities call the non-generic version of the InvokePowerShell activity, and do not expect a return value. Le altre attività usano la versione generica dell'attività InvokePowerShell e l'argomento InitializationAction per elaborare i risultati in un secondo momento.Other activities use the generic version of the InvokePowerShell activity, and use the InitializationAction argument to post-process the results.

Utilizzo del progetto PowerShellUsing the PowerShell Project

L'azione principale dell'attività si verifica nella classe ExecutePowerShell.The main action of the activity takes place in the ExecutePowerShell class. 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.Because the execution of PowerShell commands should not block the main workflow thread, the activity is created to be an asynchronous activity by inheriting from the AsyncCodeActivity class.

Il metodo BeginExecute viene chiamato dall'esecuzione del flusso di lavoro per iniziare l'esecuzione dell'attività.The BeginExecute method is called by the workflow runtime to begin running the activity. Inizia chiamando le API di PowerShell per creare una pipeline di PowerShell.It starts by calling PowerShell APIs to create a PowerShell pipeline.

runspace = RunspaceFactory.CreateRunspace();  
runspace.Open();  
pipeline = runspace.CreatePipeline();  

Successivamente crea un comando di PowerShell e lo popola con parametri e variabili.It then creates a PowerShell command and populates it with parameters and variables.

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.The inputs piped in are also sent to the pipeline at this point. Infine, la pipeline viene sottoposta a wrapping in un oggetto PipelineInvokerAsyncResult e restituita.Finally, the pipeline is wrapped in a PipelineInvokerAsyncResult object and returned. L'oggetto PipelineInvokerAsyncResult registra un listener e richiama la pipeline.The PipelineInvokerAsyncResult object registers a listener and invokes the 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.When execution finishes, output and errors are stored within the same PipelineInvokerAsyncResult object, and control is handed back to the workflow runtime by calling the callback method originally passed to BeginExecute.

Alla fine dell'esecuzione del metodo, l'esecuzione del flusso di lavoro chiama il metodo EndExecute dell'attività.At the end of the method's execution, the workflow runtime calls the activity’s EndExecute method.

La classe InvokePowerShell esegue il wrapping della classe ExecutePowerShellCommand e crea due versioni dell'attività: una generica e una non generica.The InvokePowerShell class wraps the ExecutePowerShellCommand class and creates two versions of the activity; a generic version and a non-generic version. La versione non generica restituisce direttamente l'output dell'esecuzione di PowerShell, mentre la versione generica trasforma i singoli risultati nel tipo generico.The non-generic version returns the output of the PowerShell execution directly, whereas the generic version transforms the individual results to the generic type.

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.The generic version of the activity is implemented as a sequential workflow that calls ExecutePowerShellCommand and post-processes its results. Per ogni elemento nella raccolta di risultati, la fase di post-elaborazione chiama l'oggetto InitializationAction se impostato.For each element in the result collection, the post-processing step calls InitializationAction if it is set. In caso contrario, esegue un semplice cast.Otherwise, it does a simple 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.For each of the two InvokePowerShell activities (generic, and non-generic), a designer was created. InvokePowerShellDesigner.xaml e il file con estensione cs associato definiscono l'aspetto in Progettazione flussi di lavoroWorkflow Designer per la versione non generica dell'attività InvokePowerShell.InvokePowerShellDesigner.xaml and its associated .cs file define the appearance in Progettazione flussi di lavoroWorkflow Designer for the non-generic version of the InvokePowerShell activity. In InvokePowerShellDesigner.xaml, viene usato un oggetto DockPanel per rappresentare l'interfaccia grafica.Inside InvokePowerShellDesigner.xaml, a DockPanel is used to represent the graphical interface.

<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.Note that the Text property of the text box is a two-way binding that ensures that the value of the activity’s CommandText property is equivalent to the value input into the designer.

GenericInvokePowerShellDesigner.xaml e il file con estensione cs associato definiscono l'interfaccia grafica per l'attività InvokePowerShell generica.GenericInvokePowerShellDesigner.xaml and its associated .cs file define the graphical interface for the generic InvokePowerShell activity. La finestra di progettazione è leggermente più complessa perché consente agli utenti di impostare un oggetto InitializationAction.The designer is slightly more complicated because it allows users to set an InitializationAction. L'elemento principale è l'uso dell'oggetto WorkflowItemPresenter per consentire il trascinamento delle attività figlio nell'area di progettazione di InvokePowerShell.The key element is the usage of WorkflowItemPresenter to allow drag and drop of child activities onto the InvokePowerShell designer surface.

<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.The designer customization does not stop with the .xaml files that define the appearance of the activity on the design canvas. Anche le finestre di dialogo usate per visualizzare i parametri dell'attività possono essere personalizzate.The dialog boxes used to display the parameters of the activity can also be customized. Questi parametri e le variabili PowerShell influiscono sul comportamento dei comandi di PowerShell.These parameters and PowerShell variables affect the behavior of PowerShell commands. L'attività li espone come System.Collections.Generic.Dictionary tipi.The activity exposes them as System.Collections.Generic.Dictionary types. ArgumentDictionaryEditor.cs, PropertyEditorResources.xaml e PropertyEditorResources.cs definiscono la finestra di dialogo che consente di modificare questi tipi.ArgumentDictionaryEditor.cs, PropertyEditorResources.xaml and PropertyEditorResources.cs define the dialog box that allows you to edit these types.

Per impostare, compilare ed eseguire l'esempioTo set up, build, and run the sample

È necessario installare Windows PowerShell per eseguire questo esempio.You must install Windows PowerShell to run this sample. Windows PowerShell può essere installato da questo percorso: Windows PowerShell.Windows PowerShell can be installed from this location: Windows PowerShell.

Per eseguire il progetto CodedClientTo run the coded client

  1. Aprire PowerShell.sln tramite Visual Studio 2010Visual Studio 2010.Open PowerShell.sln using Visual Studio 2010Visual Studio 2010.

  2. Fare clic con il pulsante destro del mouse sulla soluzione e compilarla.Right-click the solution and build it.

  3. Fare doppio clic su di CodedClient del progetto e selezionare imposta come progetto di avvio.Right-click the CodedClient project and select Set as Startup Project.

  4. Premere CTRL+F5 per eseguire l'applicazione.Press CTRL+F5 to run the application.

Per eseguire il progetto DesignerClientTo run the designer client

  1. Aprire PowerShell.sln tramite Visual Studio 2010Visual Studio 2010.Open PowerShell.sln using Visual Studio 2010Visual Studio 2010.

  2. Fare clic con il pulsante destro del mouse sulla soluzione e compilarla.Right-click the solution and build it.

  3. Fare doppio clic su di DesignerClient del progetto e selezionare imposta come progetto di avvio.Right-click the DesignerClient project and select Set as Startup Project.

  4. Premere CTRL+F5 per eseguire l'applicazione.Press CTRL+F5 to run the application.

Problemi notiKnown Issues

  1. 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 a InvokePowerShell.If referencing the InvokePowerShell activity assembly or project from another project results in a build error, you may need to manually add the <SpecificVersion>True</SpecificVersion> element to the .csproj file of the new project under the line that references InvokePowerShell.

  2. Se non è installato Windows PowerShell, il seguente messaggio di errore viene visualizzato in Visual Studio non appena si aggiunge un InvokePowerShell attività su un flusso di lavoro: Workflow Designer encountered problems with your document. Could not load file or assembly ‘System.Management.Automation’ ... or one of its dependencies. The system cannot find the file specified.If Windows PowerShell is not installed, the following error message is displayed in Visual Studio as soon as you add an InvokePowerShell activity onto a workflow: Workflow Designer encountered problems with your document. Could not load file or assembly ‘System.Management.Automation’ ... or one of its dependencies. The system cannot find the file specified.

  3. In Windows PowerShell 2.0, la chiamata a livello di codice di $input.MoveNext() non viene eseguita correttamente e gli script che usano $input.MoveNext() generano errori e risultati imprevisti.In Windows PowerShell 2.0, programmatically calling $input.MoveNext() fails and scripts using $input.MoveNext() produce unintended errors and results. Per risolvere questo problema, usare il verbo PowerShell foreach anziché chiamare MoveNext() quando si scorre una matrice.To work around this issue, consider using the PowerShell verb foreach instead of calling MoveNext() when iterating an array.

Importante

È possibile che gli esempi siano già installati nel computer.The samples may already be installed on your machine. Verificare la directory seguente (impostazione predefinita) prima di continuare.Check for the following (default) directory before continuing.

<InstallDrive>:\WF_WCF_Samples

Se questa directory non esiste, andare al Windows Communication Foundation (WCF) e gli esempi di Windows Workflow Foundation (WF) per .NET Framework 4 per scaricare tutti i Windows Communication Foundation (WCF) e WFWF esempi.If this directory does not exist, go to Windows Communication Foundation (WCF) and Windows Workflow Foundation (WF) Samples for .NET Framework 4 to download all Windows Communication Foundation (WCF) and WFWF samples. Questo esempio si trova nella directory seguente.This sample is located in the following directory.

<InstallDrive>:\WF_WCF_Samples\WF\Scenario\ActivityLibrary\PowerShell