C#我无法使CreateNoWindow工作 - 甚至不是msdn.com的例子

时间:2016-04-25 00:09:42

标签: c# console-application

我看过这里

https://msdn.microsoft.com/en-us/library/system.diagnostics.processstartinfo.createnowindow(v=vs.110).aspx

我理解

A)并非每个程序都尊重CreateNoWindow请求和

B)它需要UseShellExecute = False(默认为true)。

C)表示是否创建窗口。 (它不会隐藏父窗口)。它是否为子进程创建了一个窗口。 (msdn说'新窗口')

D)CreateNoWindow默认为false。

我是从cmd运行的,虽然在visual studio中点击播放说明了相同的行为。

我将CreateNoWindow设置为false,因此我认为它会为子进程创建一个新窗口。

但事实并非如此。

任务管理器显示cmd.exe的第二个实例,但您仍然可以看到一个窗口。下面是一个窗口的粘贴。它已将子cmd.exe加载到父窗口(一个cmd窗口)

如果我将CreateNoWindow设置为true或false,那么它似乎没有任何区别。

所以我显然没有在msdn链接上找到工作的例子。

C:\crp>type aaa.csc
using System.Diagnostics;

class blah{
   public static void Main(string[] args) {
          Process p = new Process();
          ProcessStartInfo psi = new ProcessStartInfo();
          psi.UseShellExecute=false; 
          psi.FileName="cmd.exe";
          psi.CreateNoWindow=false;
          p.StartInfo=psi;
          p.Start();
   }
}
C:\crp>csc aaa.csc
Microsoft (R) Visual C# Compiler version 4.0.30319.34209
for Microsoft (R) .NET Framework 4.5
Copyright (C) Microsoft Corporation. All rights reserved.


C:\crp>aaa.exe

C:\crp>Microsoft Windows [Version 6.1.7601]
Copyright (c) 2009 Microsoft Corporation.  All rights reserved.

C:\crp>

更新

它似乎确实有效。如果打开cmd提示符并运行exe,则在一种情况下,它会在父级中启动cmd.exe。在另一种情况下,它启动一个没有任何窗口的cmd.exe。视觉工作室内的行为似乎很奇怪,请参阅我对以法莲回答的评论。在Visual Studio中的这个问题中,我只尝试将项目设置为控制台应用程序,并且cmd提示窗口始终至少会弹出。对于非控制台应用程序,行为更简单,例如一个winforms应用程序。

4 个答案:

答案 0 :(得分:1)

使用Visual Studio尝试此操作并定义cmd.exe的拉文件路径

public static void Main(string[] args) {
    try 
    {
      ProcessStartInfo psi = new ProcessStartInfo();
      psi.FileName = "C:\\Windows\\System32\\cmd.exe"; // full path
      psi.CreateNoWindow = true; 
      psi.UseShellExecute = false;
      Process childProcess = Process.Start(psi); // child process
      // This code assumes the process you are starting will terminate itself. 
      // Given that is is started without a window so you cannot terminate it 
      // on the desktop, it must terminate itself or you can do it programmatically
      // from this application using the Kill method.
    }
    catch(Exception ex)
    {
        Console.WriteLine(e.Message);
    }
}

答案 1 :(得分:0)

我设置UseShellExecute=True; ....它似乎有效。

奇怪,没有那条线,你必须输入两次退出,一次关闭'关闭'子cmd.exe(它并没有真正关闭窗口)和一次关闭父cmd.exe。

答案 2 :(得分:0)

首先尝试使用cmd.exe

是最有意义的

然后从那里了解从visual studio运行时的行为

CreateNoNewWindow中的new这个词有点误导。它更像是没有窗户,甚至不使用窗户。

如果您有CreateNoNewWindow = false(默认值),那么它将在父窗口中运行该子cmd。 (这可能看起来很奇怪,但是如果你将它与CreateNoNewWindow = true时的情况进行比较那么它并不那么奇怪)。当您运行该程序时,您将看到它显示带有版权e.t.c的cmd横幅。来自在父窗口中运行的子cmd的内容。

如果您有CreateNoNewWindow = true并且您运行程序,那么它将不输出任何内容。任务管理器仍将显示第二个cmd.exe,因为它正在运行子cmd.exe,但根本不在任何cmd窗口中。

现在是视觉工作室内的行为。

使用Visual Studio控制台应用程序,当您单击播放时,Visual Studio将弹出其cmd窗口,该窗口在程序完成后消失,但任何生成的进程都将继续存在。

使用visual studio,如果你将CreateNoNewWindow设置为true(即根本不使用任何窗口),那么它将弹出其cmd窗口,在没有窗口的情况下生成第二个cmd,因此它不可见,然后父cmd窗口将关闭,生成的子cmd.exe将继续显示在任务管理器中,但没有窗口。因此任务管理器将显示一个cmd.exe,并且您将看不到任何窗口。

作为测试下面段落之前的测试,您可以创建一个cmd窗口sdfsdfds,这样您就可以使用向上箭头访问命令历史记录中的某些内容,这样您就可以查看是否在parenet命令中或不。然后开始一个子进程。输入cmd<ENTER>。现在杀死父母。孩子还在那儿。

使用visual studio,如果你将CreateNoNewWindow设置为false(即使用父窗口),(正如我们所见,即使在父进程被杀死之后,如果创建了子进程并使用该窗口,也是如此) ,在父母被杀之前然后点击播放,然后visual studio会像它一样弹出它的cmd窗口,它会产生一个子cmd.exe进程,任务管理器只显示一个cmd.exe进程,但是在一个窗口中,播放按钮再次显示为活动状态,因此程序必须已完成执行,并且父进程已完成。因此,visual studio关闭了父cmd.exe,但是孩子仍在使用父窗口,因为它是在父cmd.exe完成之前。

当visual studio项目设置为控制台应用程序时,控制台始终至少会轻弹。

但对于未作为控制台应用程序创建的项目,例如对于winforms应用程序,可以将控制台设置为隐藏,即使对于主程序,也不会弹出任何控制台或者根本不需要运行控制台。

请注意 - UseShellExecute和CreateNoWindow被设置为非默认值。 UseShellExecute默认为true,我们将其设置为false,因为当UseShellExecute为true时,CreateNoWindow会忽略其自身的值(CreateNoWindow),并创建一个新窗口(即使CreateNoWindow设置为true)。 CreateNoWindow默认为false,我们将其设置为true。如果您打算使用CreateNoWindow,那么唯一的非多余和工作用例将是UseShellExecute = false和CreateNoWindow = true。 (如果UseShellExecute = true(默认)那么你应该使用隐藏的进程窗口样式..)另外要记住这些东西适用于cmd.exe但是对于像calc.exe这样的其他东西都失败了

ProcessStartInfo psi = new ProcessStartInfo();
psi.FileName = "cmd.exe";
psi.UseShellExecute = false;
psi.CreateNoWindow = true;
Process.Start(psi);

答案 3 :(得分:0)

我终于通过正确理解CreateNoWindow找到了答案。 CreateNoWindow用于创建将覆盖目标应用程序主窗口的父窗口。

CreateNoWindow = false;

=>这将导致Process创建一个父窗口来保存目标应用程序窗口,而不是关于创建应用程序窗口

WindowStyle = ProcessWindowStyle.Hidden;

=>这将隐藏由Process创建的父窗口,而不是应用程序窗口样式

        using (Process process = new Process())
        {
            process.StartInfo.FileName = @"notepad";
            process.StartInfo.CreateNoWindow = false;
            process.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
            process.Start();
        }