2016-03-05 1 views
0

Я создаю приложение C#/WPF, которое должно взаимодействовать с PowerShell (в основном, запускать команды и скрипты). Создание процесса и его запуска не является проблемой, это довольно легко, но это становится все труднее, когда цель состоит в том, чтобы запустить его без какого-либо сценария и сделать его выполнять команды и скрипты позже:Запустите процесс PowerShell в приложении C# и взаимодействуйте с ним

  1. Запуск на C# приложение
  2. процесс запуска PowerShell параллельно
  3. [...] Есть некоторые другие вещи [...] команды
  4. Run на процесс

Я попытался несколько решений. С System.Diagnostics.Process класса, я могу запустить этот процесс, дайте ему поработать, но даже если я переориентировать потоки, запись в стандартный ввод только не работает:

var startInfo = new ProcessStartInfo() 
{ 
    FileName = "powershell.exe", 
    Arguments = "-ExecutionPolicy Bypass -NoLogo -NoExit", 
    CreateNoWindow = true, 
    RedirectStandardError = true, 
    RedirectStandardInput = true, 
    RedirectStandardOutput = true, 
    UseShellExecute = false, 
    WindowStyle = ProcessWindowStyle.Hidden 
}; 
_ps = new Process() 
{ 
    EnableRaisingEvents = true, 
    StartInfo = startInfo 
}; 
_ps.Start(); 

[...] 

_ps.StandardInput.WriteLine(TextBox_Input.Text); // No effect 

Использование System.Management.Automation.PowerShell класс не лучше, я могу подготовьте конвейер (добавьте скрипты, которые должны быть выполнены), вызовите его, но я не могу запускать скрипты, поддерживая процесс.

Мне нужно как можно скорее запустить процесс, чтобы отправлять команды и запускать их быстрее, чем я могу (и не запускать запуск процесса, что приведет к задержке).

+0

Целевая версия PowerShell? – PetSerAl

+0

Последнее: PowerShell 5.0 в Windows 10 –

+0

Создайте «Runspace» при запуске приложения, а затем назначьте все последующие экземпляры 'System.Management.Automation.PowerShell', которые вы создаете из ввода текстового поля в эту область. –

ответ

1

Как уже упоминалось в комментариях, установить (и откройте) пространство выполнения, когда приложение запускается:

Runspace rs; 
public MainWindow() 
{ 
    InitializeComponent(); 
    rs = RunspaceFactory.CreateRunspace(); 
    rs.Open(); 
} 

Теперь, все, что вам нужно, это функция, которая создает PowerShell экземпляр и запускает его в пространство выполнения:

private Collection<PSObject> RunScript(string script) 
{ 
    using(PowerShell ps = PowerShell.Create()) 
    { 
     ps.AddScript(script); 
     ps.Runspace = rs; 
     return ps.Invoke(); 
    } 
} 

А потом, в обработчик событий для запуска сценария ввода пользователем:

private void button_Click(object sender, RoutedEventArgs e) 
{ 
    Collection<PSObject> returnedObjects = RunScript(TextBox_Input.Text); 
    // do what you want with returnedObjects if necessary 
} 

Это, конечно, слишком упрощенный пример. В реальном мире вы должны проверить error and warning streams, использовать APM (BeginInvoke()/EndInvoke()) и т. Д.

+1

И если кто-то действительно хочет иметь отдельный процесс PowerShell, тогда ему необходимо изменить 'CreateRunspace()' на 'CreateOutOfProcessRunspace (null)'. – PetSerAl

+0

@PetSerAl Правильно, но из комментариев это звучит как «отдельный процесс», это было немного [XY-запрос] (http://meta.stackexchange.com/questions/66377/what-is-the-xy- проблема) –

+0

@ MathiasR.Jessen Я не пытался использовать 'Runspace' и' PowerShell' как это, и ... это работает как шарм! Спасибо, что ответили так быстро. И вы правы, это был запрос XY, мое объяснение было не очень большим, но вы все-таки нашли решение! –

 Смежные вопросы

  • Нет связанных вопросов^_^