有没有一种方法可以检查文件句柄是否有效?

3

有没有办法检查一个句柄是否有效,我的情况是由CreateFile返回的?

我面临的问题是,由CreateFile返回的一个有效文件句柄(它不是INVALID_HANDLE_VALUE)后来导致WriteFile失败,并且GetLastError声称是因为无效的句柄。


5
如果是这种情况,那么代码的其他部分必须已经关闭了该句柄。 - Vikram.exe
或者像SysInternals的Handle.exe这样的恶意工具 - Hans Passant
6个回答

2
由于您似乎在关闭句柄后没有将处理值设置为INVALID_HANDLE_VALUE,因此我建议在HANDLE变量上设置读取监视点,这将导致调试器在访问HANDLE的值时在每行代码处中断。您将能够看到变量被访问的顺序,包括何时读取变量以将其传递给CloseHandle函数。

请参见:添加监视点(在变量更改时中断)


1
其他答案都对您的问题很重要。然而,如果您已经有一个 HANDLE,并且只想弄清它是否确实是一个打开的文件句柄(而不是例如互斥体或 GDI 对象的句柄等),那么可以使用 Windows API 函数 GetFileInformationByHandle 进行检查。
根据句柄授予您的文件权限,您还可以尝试使用 ReadFile 从中读取一些数据,或者使用 nNumberOfBytesToWrite 设置为 0 的 WriteFile 执行空写操作。

1

你的问题很可能是由以下两种情况之一引起的:

  • 你可能关闭了文件句柄,但仍然尝试使用它
  • 由于内存损坏,文件句柄被覆盖

通常最好的做法是将INVALID_HANDLE_VALUE赋值给每个句柄,只要它不应包含任何有效的句柄值。简单来说,当你声明变量时,立即将其初始化为此值。并且在关闭文件句柄后立即将此值写入变量中。

这将提示你(1)——尝试使用已关闭的文件句柄(或尚未打开的文件句柄)


0

打开文件在内核中被保存为数据结构,我认为没有官方的方法来检测文件句柄是否有效,只需使用它并检查错误代码作为INVALID_HANDLE。你确定没有其他线程关闭了该文件句柄吗?


0

仅仅检查句柄的有效性是治标不治本。

你应该调试整个过程 - 在设置句柄(文件打开)的代码处设置断点,当你到达那段代码并且句柄被设置后,再设置一个条件性断点以在句柄值改变时触发。

这样可以帮助你找出根本原因,而不仅仅在每次访问时检查句柄是否有效,这种方法不可靠、代价高昂,而且在正确的逻辑下是不必要的。


这个请求有非常合理的使用情况。例如,文件句柄可能会因为集群故障或者老式的“服务器宕机”而变得无效。 - Stephane

0
只是为了补充其他人所说的,确保在调用CreateFile时检查返回值。如果失败,它将返回INVALID_HANDLE_VALUE,此时您应该调用GetLastError来查找原因。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接