2011-01-06 14 views

Odpowiedz

5

Z pewnością można to zrobić, ale trzeba użyć kodu zarządzanego, ponieważ architektura PowerShell opiera się wyłącznie na modelu obiektowym CLR.

nie jestem pewien składni C++, ale można zacząć od klasy w System.Management.Automation.dll PowerShell i używać jej metody statyczne Create utworzyć instancję, do której można dane rur i uruchomienia polecenia.

+1

Pamiętaj, że możesz również utworzyć zarządzaną bibliotekę DLL specjalnie do tego celu i użyć jednego z [rozwiązań tutaj] (http://stackoverflow.com/questions/2719985/calling-managed-c-sharp-functions-from-unmanaged -c) do wywoływania go z niezarządzanego C++. – CherryDT

2

Mam odpowiedź, która może rozwiązać Twój problem, chociaż nie jest to dosłownie odpowiedź na zadane pytanie.

Cóż, w moim obecnym projekcie potrzebuję wywołania systemowego, które nie otwiera okna i daje mi możliwość odczytania wyników zapisanych na standardowe wyjście lub błąd standardowy.

W przypadku można z tym żyć - tu jest jakiś kod z wcześniej wspomnianym kodzie:

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() : ""; 
    } 
} 

również: proszę mi wybaczyć, że kod jest w C# zamiast C++.

Jak widać, wywołuje dowolny program - i nie używa PowerShell. Jeśli to już obejście dla ciebie - w porządku. Jeśli nie, możesz rozważyć wywołanie Powershell z wiersza poleceń przy użyciu this approach i możliwe, aby tam, gdzie chcesz być w ten sposób.

Mam nadzieję, że pomaga lub przynajmniej daje ci pomysł.