我如何在 CreateFile C++ 之后管理 SHARING_VIOLATION 错误

How can i manage SHARING_VIOLATION error after a CreateFile c++

为了获得对文件的独占访问权限,我正在使用 windows api:

HANDLE handle = CreateFileW(filepath.c_str(), GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);

如果用户偶然将该文件(即文档)与其他进程一起使用,则创建文件 returns -1 作为句柄并将最后一个错误设置为 32。

我的问题如下:我怎样才能等到文件不再被其他进程使用? 做类似的事情:

while(handle==INVALID_HANDLE_VALUE)
    handle = CreateFileW(filepath.c_str(), GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);

真的很愚蠢,因为它浪费了很多资源,反复尝试。 我想有一个版本的 api 让你阻止它直到它成功,但我没有在文档中找到它!

至少据我所知,没有一个函数可以做到这一点(这并不特别令人惊讶——它几乎可以无限期地阻塞)。

由于您(显然)以 Win32 为目标,一种明显的可能性是读取目标文件的更改日志,并且只有在您看到其他进程已关闭它时才重新尝试打开它以进行独占访问(即,您看到带有 USN_REASON_CLOSE 的 USN 记录)。

没有API可以让您直接等待文件可用。您可以使用 the example code from The Old New Thing 来确定哪些进程当前有一个打开的句柄,然后等待这些进程退出并重试,但是如果打开文件的进程提前关闭了它们的句柄,您将看不到.同样,在此期间,其他进程可能已经打开了该文件,因此您无法找到一组新进程并等待它们。

在实践中,轮询循环(有一个短暂的休眠以避免不断旋转)确实是唯一的方法。您不仅要检查 INVALID_HANDLE_VALUE,而且可能要设置最大超时时间,因为当问题像权限问题或文件未找到错误那样愚蠢时,永远循环将不是一个好主意。

您可能还想查看 file in use sample on MSDN 以了解如何将问题通知用户,而不是静默轮询。