Отключение процесса от powershell, размещенного в приложении C#

У нас есть приложение C#, которое выполняет сценарии PowerShell в качестве точки расширения, у нас нет доступа для изменения этого кода, но оно примерно следующее:

string command = @"C:\temp.ps1";
var fileName = "powershell";
var args = $"-ExecutionPolicy unrestricted . '{command}'";

var process = CreateProcess(fileName, args);
ExecuteProcess(ref process);

private Process CreateProcess(string fileName, string args)
{
    return new Process
    {
        StartInfo =
        {
            FileName = fileName,
            Arguments = args,
            RedirectStandardError = true,
            RedirectStandardOutput = true,
            UseShellExecute = false
        }
    };
}

private int ExecuteProcess(ref Process proc)
{
    proc.Start();

    string text = string.Empty;
    string text2 = string.Empty;
    while (!proc.HasExited)
    {
        Thread.Sleep(1000);
        text += proc.StandardOutput.ReadToEnd();
        text2 += proc.StandardError.ReadToEnd();
    }
    proc.WaitForExit();
    text2 += proc.StandardError.ReadToEnd();
    text += proc.StandardOutput.ReadToEnd();

    Console.WriteLine(text);
    Console.WriteLine(text2);

    return proc.ExitCode;
}

У нас есть сценарий PowerShell, который запускается из этого кода, который имеет длительный процесс, поэтому для простоты мы просто используем ping.exe с аргументом -t.

ping -t google.com

Мы хотим иметь возможность разветвить процесс ping.exe, чтобы приложение C# могло возобновить выполнение как можно скорее, и чтобы ping.exe в этом примере продолжал свою работу.

Я пытался запустить Start-Process внутри сценария powershell, но это по-прежнему просто блокирует выполнение приложения С# до тех пор, пока все процессы не будут полностью выполнены (поэтому в конечном итоге он выполняется до завершения):

Start-Process ping -ArgumentList "-t","google.com" -RedirectStandardOutput ".\out.log" -RedirectStandardError ".\err.log"

Я также пытался запустить Start-Job и обернуть процесс запуска в отдельное задание, однако это, похоже, запускает задание, но никогда не завершается.

Start-Job -ScriptBlock { Start-Process ping -ArgumentList "-t","google.com" -RedirectStandardOutput ".\out.log" -RedirectStandardError ".\err.log" }

Есть ли способ запустить новый процесс из PowerShell и разрешить выполнение приложения С#?


person Kevin Smith    schedule 30.10.2017    source источник
comment
Зачем запускать ping.exe из PowerShell, если можно сделать это напрямую?   -  person Bill_Stewart    schedule 30.10.2017
comment
Ping — это просто пример, мы запускаем другие процессы в нашем скрипте PowerShell, но не хотим, чтобы он блокировался.   -  person Kevin Smith    schedule 30.10.2017
comment
Но почему вы вообще используете PowerShell? Просто создайте исполняемый файл, который вы хотите запустить.   -  person Bill_Stewart    schedule 30.10.2017
comment
Как я сказал в вопросе, у нас нет доступа к приложению C#, в котором выполняется код PowerShell, все, что у нас есть, — это только сценарии PowerShell, которые мы можем запускать.   -  person Kevin Smith    schedule 30.10.2017
comment
Start-Process запускает процесс асинхронно. Если программа C# по-прежнему блокируется, значит, она каким-то образом ожидает процессов, запущенных процессом PowerShell.   -  person Bill_Stewart    schedule 30.10.2017
comment
Ну, это просто запуск команды PowerShell из процесса PowerShell, поэтому интересно, отслеживает ли он дескрипторы внутри него.   -  person Kevin Smith    schedule 30.10.2017


Ответы (1)


Я как бы нашел обходной путь - если я перехожу от -Verb Open к Start-Process, он, кажется, сразу же возобновляет выполнение приложения С#. Единственная проблема заключается в том, что вы не можете перенаправить стандартный вывод или ошибку в файлы.

Start-Process ping -ArgumentList "-t","google.com" -Verb Open
person Kevin Smith    schedule 30.10.2017