2011-01-06 37 views
11

Tôi muốn viết một chương trình có hiệu quả "đường ống" Powershell, để tôi có thể gửi lệnh và phân tích các câu trả lời trong C++ mà không thực sự mở lời nhắc trên màn hình.Truy cập Powershell qua Visual C++ (API)

Bất kỳ mẹo nào?

Trả lời

5

Bạn chắc chắn có thể làm điều này nhưng bạn sẽ cần sử dụng mã được quản lý vì kiến ​​trúc của PowerShell dựa hoàn toàn vào mô hình đối tượng CLR.

Tôi không chắc chắn về cú pháp C++ nhưng bạn có thể bắt đầu với lớp PowerShell trong System.Management.Automation.dll và sử dụng phương thức tĩnh Create để tạo một thể hiện mà bạn có thể tạo dữ liệu đường ống và chạy lệnh.

+1

Lưu ý rằng bạn cũng có thể tạo một DLL được quản lý cụ thể cho việc này và sử dụng một trong các [giải pháp ở đây] (http://stackoverflow.com/questions/2719985/calling-managed-c-sharp-functions-from-unmanaged -c) để gọi nó từ C++ không được quản lý. – CherryDT

2

Tôi có câu trả lời có thể giải quyết được vấn đề của bạn mặc dù đây không phải là câu trả lời cho câu hỏi bạn đã đặt ra.

Vâng, những gì tôi cần trong dự án hiện tại của tôi là một cuộc gọi hệ thống không mở cửa sổ và điều đó cho tôi cơ hội đọc kết quả được viết theo tiêu chuẩn-đầu ra hoặc lỗi chuẩn.

Trong trường hợp bạn có thể sống với điều đó - đây là một số mã từ codebase trước khi nói:

public class RsbSystem 
{ 
    string command = null; 
    string param = null; 
    string commandLine = null; 
    public int ExitCode = 0; 

    //.. 

    /// <summary>Exec for apps that don't want console output</summary> 
    /// <param name="msg">returns output of called program</param> 
    /// <returns>0 if ok</returns> 
    /// <remarks>RsbSystem instance keeps the result in member ExitCode</remarks> 
    public int Exec(ref string msg) 
    { 
     var p = new Process(); 
     p.StartInfo.FileName = command; 
     p.StartInfo.Arguments = param; 
     p.StartInfo.CreateNoWindow = true; 
     p.StartInfo.UseShellExecute = false; 
     p.StartInfo.RedirectStandardOutput = true; 
     p.StartInfo.RedirectStandardError = true; 
     p.Start(); 
     if (!p.StandardOutput.EndOfStream) 
      msg = p.StandardOutput.ReadToEnd(); 
     if (!p.StandardError.EndOfStream) 
      msg += p.StandardError.ReadToEnd(); 
     p.WaitForExit(120000); // this needs to come after readToEnd() RSB: https://msdn.microsoft.com/en-us/library/system.diagnostics.processstartinfo.redirectstandardoutput(v=vs.110).aspx 
     ExitCode = p.ExitCode; 
     p.Dispose(); 
     return ExitCode; 
    } 

    // .. 

    public RsbSystem(string cmdLine) 
    { 
     commandLine = cmdLine; 
     var pos = 0; 
     if (cmdLine[0] == '"') 
      pos = cmdLine.IndexOf("\" ") + 1; 
     else pos = cmdLine.IndexOf(" "); 
     command = pos > -1 ? cmdLine.Substring(0, pos).Trim() : cmdLine; 
     param = pos > -1 ? cmdLine.Substring(pos + 1).TrimStart() : ""; 
    } 
} 

Ngoài ra: xin vui lòng tha thứ cho tôi rằng mã là trong C# thay vì C++.

Như bạn có thể thấy nó gọi bất kỳ chương trình nào - và không sử dụng PowerShell. Nếu đó là một giải pháp cho bạn - tốt. Nếu không, bạn có thể xem xét việc gọi Powershell từ dòng lệnh bằng cách sử dụng this approach và có thể nhận được nơi bạn muốn theo cách đó.

Hy vọng nó sẽ giúp hoặc ít nhất là cung cấp cho bạn một ý tưởng.

Các vấn đề liên quan