【问题标题】:C# How to Hide PowerShell WindowC# 如何隐藏 PowerShell 窗口
【发布时间】:2017-11-14 19:34:58
【问题描述】:

我在 WPF 应用程序中使用 PowerShell 命令时遇到了问题。这里的基本要求是 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 上下文,另一方面隐藏控制台窗口?

【问题讨论】:

  • 您尝试过使用以下StartInfo.WindowStyle =.ProcessWindowStyle.Hidden;
  • 在我的第二个代码 sn-p 中,我使用该过程隐藏了 PowerShell 窗口。但是,我不喜欢这种方法,因为我不能重用 PowerShell 上下文。例如,每次运行命令时我都必须导入模块。但是,通过使用 RunSpace,我可以重用上下文。但是 RunSpace 的问题是我无法隐藏窗口。所以,请问有高手知道吗?

标签: c# powershell


【解决方案1】:

我使用以下内容创建了一个控制台应用程序,但根本看不到任何 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();
    }));

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-12
    • 2013-09-03
    • 1970-01-01
    • 2011-01-08
    • 2010-10-10
    相关资源
    最近更新 更多