Подтвердить что ты не робот

Доступ к Powershell через Visual С++ (API)

Я бы хотел написать программу, которая эффективно "трубит" Powershell, так что я могу отправлять команды и анализировать ответы на С++, фактически не открывая приглашение на экране.

Любые советы?

4b9b3361

Ответ 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 из командной строки, используя этот подход и, возможно, получите то, где вы хотите быть таким образом.

Надеюсь, что это поможет или, по крайней мере, дает вам идею.