Доступ к Powershell через Visual С++ (API)
Я бы хотел написать программу, которая эффективно "трубит" Powershell, так что я могу отправлять команды и анализировать ответы на С++, фактически не открывая приглашение на экране.
Любые советы?
Ответы
Ответ 1
Вы можете это сделать, но вам нужно использовать управляемый код, поскольку архитектура PowerShell полностью основана на объектной модели CLR.
Я не уверен в синтаксисе С++, но вы можете начать с класса PowerShell в System.Management.Automation.dll и используйте свой статический метод Create, чтобы создать экземпляр, к которому вы можете передавать данные и запускать команды.
Ответ 2
У меня есть ответ, который может решить вашу проблему, хотя это не буквально ответ на заданный вами вопрос.
Ну, что мне нужно в моем текущем проекте - это системный вызов, который не открывает окно, и это дает мне возможность считывать результаты, записанные на стандартный вывод или стандартную ошибку.
Если вы можете жить с этим - вот какой-то код из вышеупомянутой кодовой базы:
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() : "";
}
}
Также: пожалуйста, простите, что код находится на С# вместо С++.
Как вы можете видеть, он вызывает любую программу - и не использует PowerShell. Если это уже обходное решение для вас - отлично. Если нет, вы можете подумать о вызове Powershell из командной строки, используя этот подход и, возможно, получите то, где вы хотите быть таким образом.
Надеюсь, что это поможет или, по крайней мере, дает вам идею.