这是一个在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*
函数底层的复杂内容中,以查看在哪一点窗口出现。
答案 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,则问题就会消失。