2017-11-13 12 views
0

WPFアプリケーションでPowerShellコマンドを使用して問題が発生しました。ここでの基本的な要件は、コンソールウィンドウをポップアップさせずにPowerShellをバックグラウンドで実行することです。C#PowerShellウィンドウを非表示にする方法

しかし、私がRunSpaceを作成してPipelineでコマンドを実行すると、コンソールウィンドウを隠すことができません。以下は私のコードです:

private void RunAppCapture() 
{ 
    var initial = InitialSessionState.CreateDefault(); 
    initial.ImportPSModule(new[] { "vmware.appcapture" }); 

    var runSpace = RunspaceFactory.CreateRunspace(initial); 
    runSpace.Open(); 

    Pipeline pipeline = runSpace.CreatePipeline(); 

    Command capture = new Command("Start-AVAppCapture"); 
    capture.Parameters.Add("Name", "Test"); 
    pipeline.Commands.Add(capture); 

    StringBuilder stringBuilder = new StringBuilder(); 

    pipeline.Invoke(); 
    if (pipeline.Error.Count > 0) 
    { 
     while (!pipeline.Error.EndOfPipeline) 
     { 
      stringBuilder.AppendLine(pipeline.Error.Read().ToString()); 
     } 
    } 
    runSpace.Close(); 

    try 
    { 
     Result.Dispatcher.Invoke(new Action(() => 
     { 
      Result.Text = stringBuilder.ToString(); 
     })); 
    } 
    catch (Exception e) 
    { 
    } 
} 

唯一の方法は、プロセス内でPowerShellを実行することです。しかし、毎回まったく新しいPowerShellプロセスを開始しているので、コンテキストを再利用することはできません。私のコードは以下の通りです:

private void RunPowerShellProcess() 
{ 
    ProcessStartInfo startInfo = new ProcessStartInfo(); 
    Process p = new Process(); 

    startInfo.CreateNoWindow = true; 
    startInfo.RedirectStandardOutput = true; 
    startInfo.RedirectStandardInput = true; 
    startInfo.RedirectStandardError = true; 

    startInfo.UseShellExecute = false; 
    startInfo.Arguments = "import-module vmware.appcapture;Start-AVAppCapture -Name Test"; 
    startInfo.FileName = "Powershell.exe"; 

    p.StartInfo = startInfo; 
    StringBuilder stringBuilder = new StringBuilder(); 
    p.OutputDataReceived += new DataReceivedEventHandler 
    (
     delegate(object sender, DataReceivedEventArgs e) 
     { 
      using (StreamReader output = p.StandardOutput) 
      { 
       stringBuilder.AppendLine(output.ReadToEnd()); 
      } 
     } 
    ); 
    p.ErrorDataReceived += new DataReceivedEventHandler 
    (
     delegate(object sender, DataReceivedEventArgs e) 
     { 
      using (StreamReader output = p.StandardError) 
      { 
       stringBuilder.AppendLine(output.ReadToEnd()); 
      } 
     } 
    ); 


    p.Start(); 
    p.WaitForExit(); 

    string finalStdOuputLine = p.StandardOutput.ReadToEnd(); 
    string finalStdErrorLine = p.StandardError.ReadToEnd(); 
    try 
    { 
     Result.Dispatcher.Invoke(new Action(() => 
     { 
      Result.Text = String.Format("Result: {0}, Error: {1}", finalStdOuputLine, finalStdErrorLine); 
     })); 
    } 
    catch (Exception e) 
    { 
    } 
} 

私は本当にRunSpaceを使いたいと思います。しかし、一方でPowerShellのコンテキストを再利用するにはどうしたらいいですか?一方、コンソールウィンドウを隠すにはどうしたらいいですか?

+0

は、あなたの使って試してみましたが、次の 'StartInfo.WindowStyle = .ProcessWindowStyle.Hidden;'私の第二のコードスニペットでは、私はPowerShellウィンドウを非表示にするプロセスを使用し – MethodMan

+0

。しかし、PowerShellのコンテキストを再利用することはできないので、私はこの方法が嫌いです。たとえば、コマンドを実行するたびにモジュールをインポートする必要があります。しかし、RunSpaceを使って、私は文脈を再利用することができます。しかし、RunSpaceの問題は、私がウィンドウを隠すことができないということです。したがって、私は専門家がそれを知っているかどうか尋ねていますか? – Fiona

答えて

0

次のようなコンソールアプリケーションを作成しましたが、パワーウィンドウのウィンドウが全く表示されませんでした。私は日常的にRunSpaceクラスとRunSpacePoolクラスを使い、PowerShellのインスタンスが見えるようになったことは一度もありません。

public static void Main(string[] args) 
    { 
     var initial = InitialSessionState.CreateDefault(); 
     initial.ImportPSModule(new[] { "BITSTransfer" }); 

     var runSpace = RunspaceFactory.CreateRunspace(initial); 
     runSpace.Open(); 

     for (int i = 0; i < 5; i++) 
     { 
      using (Pipeline pipeline = runSpace.CreatePipeline()) 
      { 
       Command capture = new Command("Get-Command"); 
       capture.Parameters.Add("Module", "BITSTransfer"); 
       pipeline.Commands.Add(capture); 
        Console.WriteLine(string.Format("In loop {0}", i)); 
        System.Collections.ObjectModel.Collection<PSObject> outputCollection = pipeline.Invoke(); 
        foreach (PSObject item in outputCollection) 
        { 
         Console.WriteLine(item.BaseObject.ToString()); 
        } 
       } 
      } 
     } 

     runSpace.Close(); 
     Console.ReadLine(); 
    } 

ご覧のとおり、これはランスペースを作成し、モジュールをインポートします。次にパイプラインを作成し、そのモジュールのコマンドを5回画面に書き込みます。毎回同じランスペースを使用します。パワーシェルウィンドウは生成されませんでした。

私はこれが何をしているのか分かりませんし、あなたが参照しているウィンドウを産み出す責任もないとは確信していません。

Result.Dispatcher.Invoke(new Action(() => 
    { 
     Result.Text = stringBuilder.ToString(); 
    })); 
関連する問題