C# - 启动Invisible Process(CreateNoWindow& WindowStyle不工作?)

时间:2010-06-10 02:14:38

标签: c# .net winforms process processstartinfo

我有两个程序(.exe),我在.NET中创建。我们称他们为师父和工人。大师启动1个或更多工人。工作人员将与用户进行交互,但它是一个WinForms应用程序,它接收命令并根据从主服务器接收的命令运行WinForms组件。

我希望Worker应用程序完全隐藏(当然,除了显示在任务管理器中)。我认为我可以使用 StartInfo.CreateNoWindow StartInfo.WindowStyle 属性完成此操作,但我仍然在表单中看到Client.exe窗口和组件。但是,它不会显示在任务栏中。

   Process process = new Process
      {
          EnableRaisingEvents = true,
          StartInfo =
              {
                  CreateNoWindow = true,
                  WindowStyle = ProcessWindowStyle.Hidden

                  FileName = "Client.exe",
                  UseShellExecute = false,
                  ErrorDialog = false,
              }
      };

我需要做什么让Client.exe运行但不显示?

4 个答案:

答案 0 :(得分:7)

您对CreateNoWindow / WindowStyle的使用在我的系统上使用notepad.exe正常(例如它隐藏但在后台运行),所以它可能是WinForms应用程序正在做的事情。一些想法:

选项1:如果您控制WinForms工作进程,则可以覆盖Control.SetVisibleCore以始终隐藏表单。如果您不想总是隐藏它,可以将命令行参数传递给它,例如/hide会导致它被隐藏。示例(假设表单已经存在代码隐藏):

public partial class MyForm : Form
{
    public MyForm()
    {
        InitializeComponent();
    }

    protected override void SetVisibleCore(bool value)
    {
        // You'd probably want to parse the command line.
        if (Environment.CommandLine.Contains("/hide"))
            base.SetVisibleCore(false);
        else
            base.SetVisibleCore(value);
    }
}

有了这个,运行MyForm.exe会导致一个具有可见表单的进程。运行MyForm.exe /hide会导致具有隐藏表单的进程。您可以从主进程传递/hide参数,因此运行该应用程序的普通用户仍然可以看到它。

选项2:您可以通过对ShowWindow进行P / Invoke来隐藏应用程序。有关此here的更多信息。这样做的缺点是,在隐藏之前,您有时可以看到工作窗口闪烁。例如:

class Program
{
    public static void Main(string[] args)
    {
        ProcessStartInfo psi = new ProcessStartInfo()
        {
            FileName = @"C:\windows\system32\notepad.exe",
        };

        Process process = Process.Start(psi);

        // Wait until the process has a main window handle.
        while (process.MainWindowHandle == IntPtr.Zero)
        {
            process.Refresh();
        }

        ShowWindow(process.MainWindowHandle, SW_HIDE);
    }

    const int SW_HIDE = 0;

    [DllImport("user32.dll")]
    static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
}

答案 1 :(得分:5)

问题在于UseShellExecute = false,将其设置为true,并且该过程将以隐藏方式启动。使用shell启动进程可以理解如何隐藏应用程序,直接用UseShellExecute = false启动进程直接启动进程,正如Chris Schmich所提到的那样,你必须处理隐藏窗口的问题。客户申请。如果您希望手动运行应用程序以进行调试或测试,则可能需要这样做。

答案 2 :(得分:0)

您必须在Win Form应用程序构造函数中添加base.Visibility = Visibility.Hidden;

答案 3 :(得分:0)

由于我的声誉太低,我只能发表我的答案,可以评论克里斯·施米奇的答案。

在开始进程之前,可以设置 WindowStyle = ProcessWindowStyle.Minimized 以避免窗口闪烁。

这是我的代码:

private const int SW_HIDE = 0;

[DllImport("user32.dll")]
private static extern bool ShowWindow(IntPtr hwnd, int nCmdShow);

public int RunWithoutWindow(string exePath)
{
    var startInfo = new ProcessStartInfo(exePath)
    {
        WindowStyle = ProcessWindowStyle.Minimized
    };

    var process = Process.Start(startInfo);

    while (process.MainWindowHandle == IntPtr.Zero)
    {
        process.Refresh();
    }

    ShowWindow(process.MainWindowHandle, SW_HIDE);

    return process.Id;
}

最后感谢Chris Schmich提供的良好答案,而 ProcessWindowStyle.Hidden 有时不起作用。