【问题标题】:Find open handles within a Windows program在 Windows 程序中查找打开的句柄
【发布时间】:2013-09-12 15:23:14
【问题描述】:

在 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);

这在 Windows 中似乎不起作用。

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

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

【问题讨论】:

  • 这似乎在 Windows 中不起作用是什么意思?
  • 我的意思是,它运行没有错误,但文件仍然打开。
  • @alk,像这样盲目地关闭窗口句柄可不是什么好事。
  • 如果您可以控制父进程,则让它为 CreateProcessbInheritHandles 标志传递 FALSE。

标签: c windows mingw


【解决方案1】:

我现在对此进行了一些调查,并找到了解决实际问题的方法,但不是我想要的。

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

我现在有两个选择:

  1. 在父(调用)进程中放置一些特殊情况代码,使其调用CreateProcess,并在适当的时候禁用继承(它目前使用_spawnlp,因为它与Unix风格的管道和文件句柄兼容,并且您不能将CreateProcess 与那些非常可靠的人一起使用)。

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

第一个感觉更有效率。第二个更灵活(它允许进程自己选择)。

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

【讨论】:

    【解决方案2】:

    首先是一些背景信息——为什么循环在 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 混合了不同类型的句柄(文件句柄、内存句柄、进程句柄……)。如果您可以获得所有句柄的列表,您将不得不以不同的方式对待它们。

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

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

    【讨论】:

    • 这个答案没有解决问题。
    猜你喜欢
    • 1970-01-01
    • 2013-12-16
    • 2013-04-22
    • 1970-01-01
    • 2010-11-09
    • 2010-09-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多