Chciałbym napisać program, który efektywnie "pikuje" Powershell, dzięki czemu mogę wysyłać polecenia i parsować odpowiedzi w C++, bez faktycznego otwierania monitu na ekranie.Access Powershell poprzez Visual C++ (API)
Jakieś wskazówki?
Chciałbym napisać program, który efektywnie "pikuje" Powershell, dzięki czemu mogę wysyłać polecenia i parsować odpowiedzi w C++, bez faktycznego otwierania monitu na ekranie.Access Powershell poprzez Visual C++ (API)
Jakieś wskazówki?
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.
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ł.
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