2012-11-06 37 views
5

Tôi đang sử dụng System.Management.Automation DLL cho phép tôi gọi PowerShell bên trong ứng dụng C# của tôi như vậy:Calling PowerShell Từ C#

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

Những gì tôi đang cố gắng làm là gọi PowerShell nhưng cung cấp danh sách đầu vào. Ví dụ, trong:

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

Tôi cố gắng để cung cấp phía bên tay trái 1, 2, 3 khi gọi:

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

Tuy nhiên điều này không hoạt động. Các workaround tôi đã đưa ra được sử dụng ForEach-Object và sau đó đi qua các mảng như một InputObject với { $_ } như 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(); 

Mặc dù đoạn mã trên đang làm việc là có cách nào sử dụng Invoke đi qua trong đầu vào mảng bởi vì tôi sẽ có mặc dù rằng đây sẽ là cách mong muốn gọi nó?

Trả lời

8

Một chút muộn nhưng:

    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); 
       } 

lợi nhuận exactely:

2 
4 
6 
+0

Tác phẩm này hoạt động nhưng bạn đang chuyển '1,2,3' thành chuỗi thay vì một mảng tức là' new int [] {1,2,3} '. Điều thứ hai là cần thiết nếu tôi chuyển dữ liệu có cấu trúc đến đường ống. –

+0

@TahirHassan Cách duy nhất tôi biết để vượt qua đối tượng .net được tạo ra đang sử dụng 'SessionStateProxy.SetVariable (tên chuỗi, giá trị đối tượng)'. Nhìn vào câu trả lời đã chỉnh sửa của tôi. –

+0

Bạn đã trả lời câu hỏi của tôi về cách bắt đầu đường ống với một mảng (không chuyển nó đến 'ForEach-Object' bằng tham số' InputObject' như được mô tả trong câu hỏi của tôi). Cảm ơn. –

2

Tôi đã thực hiện nghiên cứu của mình và PowerShell.Invoke(IEnumerable) sẽ đặt InputObject của lệnh đầu tiên trong danh sách. Do đó, thay vì đặt InputObject trên inputCmd ở trên, thay vào đó, chúng tôi có thể chuyển nó qua phương thức Invoke. Chúng tôi vẫn cần cuộc gọi ForEach-Object đầu tiên để chuyển mảng đầu vào đến.

+0

tặng một cố gắng để trả lời của tôi. –

+0

Đây là thiên tài! Tôi sẽ không bao giờ tìm kiếm nó ở đó! – t3chb0t