如何处理CreateFile c++后的SHARING_VIOLATION错误?

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

本文关键字:SHARING 后的 VIOLATION 错误 c++ CreateFile 何处理 处理      更新时间:2023-10-16

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

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

如果用户碰巧正在与其他进程一起使用该文件(即doc),则create files返回-1作为句柄,并将最后一个错误设置为32。

我的问题是:我怎么能等到文件不再被其他进程使用?执行如下命令:

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

非常愚蠢,因为它浪费了大量的资源,一次又一次地尝试。我猜有一个版本的api可以让你阻止它,直到它成功,但我没有在文档中找到它!

没有API允许您等待文件直接可用。您可以使用the Old New Thing中的示例代码来确定哪些进程当前有一个打开的句柄,然后等待这些进程退出并再次尝试,但是如果打开了文件的进程提前关闭了它们的句柄,则不会看到这种情况。同样,在此期间,其他进程可能已经打开了该文件,因此您将无法找到一组新的进程并等待它们。

在实践中,轮询循环(具有短睡眠以避免不断旋转)实际上是实现此目的的唯一方法。您可能想要检查的不仅仅是INVALID_HANDLE_VALUE,并且可能想要设置一个最大超时,因为当问题是诸如权限问题或未找到文件错误之类的愚蠢问题时,永远循环将是一个坏主意。

您可能还想查看MSDN上使用示例中的文件,以了解如何通知用户问题,而不仅仅是静默轮询。

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

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