C#如何隐藏PowerShell窗口

时间:2017-11-13 22:45:00

标签: c# powershell

我在WPF应用程序中使用PowerShell命令遇到了问题。这里的基本要求是PowerShell应该在后台运行而不会弹出任何控制台窗口。

但是,如果我创建一个RunSpace并在管道中运行该命令,我根本无法隐藏控制台窗口。以下是我的代码:

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上下文,另一方面隐藏控制台窗口?

1 个答案:

答案 0 :(得分:0)

我使用以下内容创建了一个控制台应用程序,并且没有任何可见的PowerShell窗口。我经常使用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次。每次使用相同的运行空间。没有出现powershell窗口。

我不确定这是做什么的,我也不确定它是否负责产生你引用的窗口。

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