【问题标题】:C# I can't get CreateNoWindow to work - not even the msdn.com exampleC# 我无法让 CreateNoWindow 工作 - 甚至 msdn.com 示例
【发布时间】:2016-08-18 05:47:03
【问题描述】:

我看过这里

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窗口)中加载了子cmd.exe

如果我将 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应用程序。

【问题讨论】:

    标签: c# console-application


    【解决方案1】:

    通过对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();
            }
    

    【讨论】:

      【解决方案2】:

      首先从 cmd.exe 尝试最有意义

      然后从那里了解从 Visual Studio 运行时的行为

      CreateNoNewWindow 中的 new 一词有点误导。更像是不创建窗口,甚至不使用窗口。

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

      如果你有 CreateNoNewWindow=true 并且你运行你的程序,那么它不会输出任何东西。任务管理器仍然会显示第二个 cmd.exe,这是因为它正在运行子 cmd.exe,但根本不在任何 cmd 窗口中。

      现在是 Visual Studio 中的行为。

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

      使用visual studio,如果你将CreateNoNewWindow设置为true(即完全不使用窗口),那么它会弹出它的cmd窗口,在no window中生成第二个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(default) 那么你应该使用隐藏的进程窗口样式。)另外请记住,这些东西适用于 cmd.exe,但对于 calc.exe 等其他一些东西会失败

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

      【讨论】:

        【解决方案3】:

        我设置了UseShellExecute=True; ....它似乎工作。

        奇怪的是,如果没有该行,您必须输入两次 exit,一次是“关闭”子 cmd.exe(它不会真正关闭窗口),一次是关闭父 cmd.exe。

        【讨论】:

        • 当你说它有效时,你称之为有效。当你有那条线时。那么 CreateNoWindow 有什么不同吗?我想你会发现 UseShellExecute,然后 CreateNoWindow 被忽略..正如 msdn 链接所说。因此它不会“让它发挥作用”。
        • 如果没有 UseShellExecute true 行,即它为 false,无论 CreateNoWindow(即使 CreateNoWindow 设置为 false),它似乎都不会创建新的 cmd 窗口,这就是问题所在,.但是无论如何,在同一个cmd窗口内执行cmd的情况下,必须输入两次exit是正常的。尝试打开一个 cmd 窗口,然后输入 cmd<ENTER> cmd<ENTER> 你会看到它在 cmd 中打开了 cmd,如果你点击向上箭头,你不会看到命令历史记录,因为它是一个新实例,你必须输入 exit多次退出原来的cmd窗口。
        • “当你说它有效时,你称之为有效。”它按预期创建了第二个 cmd.exe 窗口。有人在将属性命名为 CreateNoWindow 时做出了错误的决定。它会导致讨厌的双重否定。 CreateNoWindow = false 会更好CreateWindow = true
        • 正如所问的,当你有那条线时,CreateNoWindow 有什么不同吗?
        • @barlop 我不知道,我没试过。如果你真的想知道,我想可以试试。
        【解决方案4】:

        使用 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);
            }
        }
        

        【讨论】:

        • 这似乎在从 Visual Studio 完成时有所不同,但从 cmd 完成时却没有。这似乎很奇怪/在 Visual Studio 的一组 CreateNoWindow 中,它在运行子时保持 cmd 窗口打开过程。在另一种情况下,它会关闭它。我仍然没有看到这与 CreateNoWindow 背后的含义有什么关系
        • 另外,是否使用完整路径以及使用 proc.Start() 或 Process.Start(psi) 似乎都没有区别。我已经发布了对我的问题的更新,并且我已经发布了答案。由于您的回答有帮助,我会为您投票。
        猜你喜欢
        • 2017-04-03
        • 1970-01-01
        • 2015-12-16
        • 1970-01-01
        • 2018-09-03
        • 1970-01-01
        • 2013-11-26
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多