Cygwin:调用spawnvp会导致非控制台程序有一个控制台窗口

时间:2016-06-29 19:19:08

标签: cygwin

这是一个在Windows 7下使用Cygwin 2.5.2重现行为的小程序。

#include <windows.h>
#include <process.h>

int main(void)
{
   const char * const argv[] = {
     "c:/Windows/System32/notepad.exe",
     0
   };

   Sleep(5000);
   return spawnvp(_P_WAIT, argv[0], argv);
}

这构建如下:

$ gcc -mwindows spawn.c -o spawn

好处:正确地说,此程序不以控制台窗口启动。我们可以使用Windows资源管理器导航到其目录并启动它。当程序开始执行并到达Sleep(5000)语句时,屏幕上不显示任何内容。

糟糕:经过五秒后,执行spawnvp调用,程序获得一个控制台窗口!记事本启动,其窗口显示在此控制台窗口的顶部。

有人可以解释为什么,以及如何让它消失?只有记事本应该显示,而不是任何虚假的控制台窗口。

当然,如果我们生成一个控制台程序,程序应该有自己的控制台窗口。这不是问题所在; 正在获取不需要的窗口(而且孩子根本不是控制台程序)。

更新:我现在正在重建Cygwin,希望能够将一些调试打印语句添加到spawn*函数底层的复杂内容中,以查看在哪一点窗口出现。

1 个答案:

答案 0 :(得分:1)

我跟踪了这​​个。所有Cygwin spawn*exec*来电均通过spawne,后者依赖child_info_spawn::worker类成员函数,在winsup/cygwin/spawn.cc中实现。

此功能包含以下内容:

  if (mode == _P_DETACH)
    c_flags |= DETACHED_PROCESS;
  else
    fhandler_console::need_invisible ();

罪魁祸首是调用此fhandler_console::need_invisible来分配控制台。出于某种原因,Cygwin认为如果调用应用程序还没有创建一个隐藏的控制台窗口,则需要创建一个不可见的控制台窗口。不幸的是,制作这个隐形窗户的计划并没有按计划进行;我们得到一个可见的窗口。

如果我将此调用注释掉need_invisible并重建Cygwin DLL,则问题就会消失。