2012-11-06 23 views
5

Używam System.Management.Automation DLL, który pozwala mi zadzwonić PowerShell wewnątrz mojej aplikacji C# tak:Wywoływanie PowerShell z C#

PowerShell.Create().AddScript("Get-Process").Invoke(); 

Co staram się zrobić to zadzwonić PowerShell ale dostarczy listę wejściową. Na przykład, w:

1, 2, 3 | ForEach-Object { $_ * 2 } 

staram się dostarczać lewej stronie 1, 2, 3 podczas wywoływania:

// powershell is a PowerShell Object 
powershell.Invoke(new [] { 1, 2, 3 }); 

Jednak to nie działa. obejście wymyśliłem używał ForEach-Object, a następnie przepuszczanie tablicy jako InputObject z { $_ } jak Process:

// create powershell object 
var powershell = PowerShell.Create(); 

// input array 1, 2, 3 
Command inputCmd = new Command("ForEach-Object"); 
inputCmd.Parameters.Add("InputObject", new [] { 1, 2, 3 }); 
inputCmd.Parameters.Add("Process", ScriptBlock.Create("$_")); 
powershell.Commands.AddCommand(inputCmd); 

// ForEach-Object { $_ * 2 } 
Command outputCmd = new Command("ForEach-Object"); 
outputCmd.Parameters.Add("Process", ScriptBlock.Create("$_ * 2")); 
powershell.Commands.AddCommand(outputCmd); 

// invoke 
var result = powershell.Invoke(); 

Chociaż kod powyżej działa tam sposób wykorzystania Invoke przechodząc na wejściu tablicy, ponieważ chciałbym, aby był to pożądany sposób nazywania go?

Odpowiedz

8

Trochę późno, ale:

    PowerShell ps = PowerShell.Create(); 
    ps.Runspace.SessionStateProxy.SetVariable("a", new int[] { 1, 2, 3 }); 
    ps.AddScript("$a"); 
    ps.AddCommand("foreach-object"); 
    ps.AddParameter("process", ScriptBlock.Create("$_ * 2")); 
    Collection<PSObject> result = ps.Invoke(); 
    foreach (PSObject result in results) 
       { 
        Console.WriteLine(result); 
       } 

powraca exactely:

2 
4 
6 
+0

Działa to, ale przekazujesz '1,2,3' jako ciąg, a nie tablicę, np.' New int [] {1,2,3} '. Drugi jest potrzebny, jeśli mam przekazać dane strukturalne do potoku. –

+0

@TahirHassan Jedynym sposobem, w jaki mogę przekazać utworzony obiekt .net jest użycie 'SessionStateProxy.SetVariable (nazwa ciągu, wartość obiektu)'. Spójrz na moją zredagowaną odpowiedź. –

+0

Odpowiedziałeś mi na pytanie, jak uruchomić potok z tablicą (bez przekazywania jej do 'ForEach-Object' przy użyciu parametru' InputObject', jak opisano w moim pytaniu). Dzięki. –

2

Zrobiłem moje badania i PowerShell.Invoke(IEnumerable) ustawi InputObject pierwszego polecenia na liście. Dlatego zamiast ustawić InputObject na inputCmd powyżej, możemy zamiast tego przepuścić go przez metodę Invoke. Nadal potrzebujemy pierwszego wywołania ForEach-Object, aby przekazać tablicę wejściową do.

+0

Daj spróbować moją odpowiedź. –

+0

To jest geniusz! Nigdy bym go nie szukał! – t3chb0t