C 在Windows程序中查找打开的句柄

C 在Windows程序中查找打开的句柄,c,windows,mingw,C,Windows,Mingw,在Windows(MinGW)中,我的程序从调用进程继承不需要的句柄 这个过程不需要打开这些文件,但是因为它的存在时间超过了父进程的生命周期,所以我遇到了文件保持打开的常见问题 在Linux上,我修复了如下问题: // Close all file descriptors // It's hard to figure out how many are open, but the first 1000 should do int fd; for (fd = 0; fd < 1000; fd+

在Windows(MinGW)中,我的程序从调用进程继承不需要的句柄

这个过程不需要打开这些文件,但是因为它的存在时间超过了父进程的生命周期,所以我遇到了文件保持打开的常见问题

在Linux上,我修复了如下问题:

// Close all file descriptors
// It's hard to figure out how many are open, but the first 1000 should do
int fd;
for (fd = 0; fd < 1000; fd++)
  close (fd);
//关闭所有文件描述符
//很难计算有多少是开放的,但前1000个应该可以
int-fd;
对于(fd=0;fd<1000;fd++)
关闭(fd);
这在Windows中似乎不起作用

如何确定继承了哪些文件句柄?我怎样才能关闭它们


该项目是使用MinGW和Windows的Unix兼容API用C(无C++)编写的。

首先是一些背景信息-为什么循环在Windows下不起作用:

在Linux中,句柄有数字0…n。传递给“close()”和类似函数的句柄直接传递给操作系统:

void close(int handle)
{
    syscall(SYS_CLOSE,handle);
}
但是,在Windows中,操作系统使用自己的句柄,类似于指针地址,C库使用某种类型的转换表:

void close(int handle)
{
    CloseHandle(table[handle]);
    table[handle]=NULL;
}
如果句柄保持打开状态,则C库不知道(不是STDIN、STDOUT、STDERR),这些句柄将不在表中

现在谈谈实际问题:

与Linux不同,Windows混合了不同类型的句柄(文件句柄、内存句柄、进程句柄等)。如果你能得到一个所有句柄的列表,你将不得不以不同的方式对待dem

另一点是Windows库在内部使用一些句柄。如果您只是关闭父进程继承的所有句柄,您将面临程序崩溃的风险,因为Windows库可能依赖于其中的一些句柄


因此,确保没有句柄保持打开状态完全取决于父应用程序。默认情况下,句柄不会在Windows中继承。然而,C库包装器(例如“fopen()”)将设置“继承句柄”标志,以便句柄将被继承。

我现在对此进行了一些研究,并找到了解决实际问题的方法,但不是我所期望的方法

我原以为我能够找到并清理任何不需要的打开文件,但事实证明这很难。我找到了一些不同的教程(,和)如何做到这一点,但它们依赖于未记录的API。我无法让这项技术发挥作用——可能是我做错了,也可能是Windows Server 2012中的API发生了变化——但无论如何,我不确定我是否想去那里;Sysinternals可以跟踪这些东西并保持Process Explorer正常工作,但我不希望在我的项目上有这样的维护负担

我现在有两个选择:

  • 在父进程(调用)中放入一些特殊情况代码,使其在适当的时候调用
    CreateProcess
    ,并禁用继承(它当前使用
    \u spawnlp
    ,因为它与Unix样式的管道和文件句柄兼容,并且不能非常可靠地使用
    CreateProcess

  • 让进程立即使用
    CreateProcess
    调用自己,然后退出(或无限期等待),以终止任何不需要的句柄

  • 第一种感觉更有效。第二个更灵活(它允许流程自行选择)


    我想我会选择选项一,因为就我目前的需要而言,它感觉最差。

    这是什么意思?在Windows中似乎不起作用?我的意思是,它运行时没有错误,但文件保持打开状态。可能是一个起点。@alk,像这样盲目地关闭windows句柄不是一件好事。如果你控制了父进程,那么让它为
    CreateProcess
    bInheritHandles
    标志传递FALSE。这个答案并没有解决这个问题。