Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/70.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
检查是否正在使用Win32 API或C/C++;。我自己没有写权限_C_Windows_File_Winapi_Visual C++ - Fatal编程技术网

检查是否正在使用Win32 API或C/C++;。我自己没有写权限

检查是否正在使用Win32 API或C/C++;。我自己没有写权限,c,windows,file,winapi,visual-c++,C,Windows,File,Winapi,Visual C++,在Windows C/C++程序中,我需要处理一个文本文件。所以我只需要打开文件进行阅读。但是,我不希望在文件仍由另一个进程写入时执行此操作。我还知道,另一个进程最终将关闭该文件,并且再也不会写入该文件 看看stackoverflow上类似的问题,典型的答案是“尝试打开文件进行写入-如果失败,请稍后再试”) 现在在本例中,我的进程根本没有对文件的写访问权。因此,检查文件是否可以打开进行写入不是一个选项。无论其他进程是否具有写访问权限,它都将始终失败。正如Hans Passant和Igor Tan

在Windows C/C++程序中,我需要处理一个文本文件。所以我只需要打开文件进行阅读。但是,我不希望在文件仍由另一个进程写入时执行此操作。我还知道,另一个进程最终将关闭该文件,并且再也不会写入该文件

看看stackoverflow上类似的问题,典型的答案是“尝试打开文件进行写入-如果失败,请稍后再试”)


现在在本例中,我的进程根本没有对文件的写访问权。因此,检查文件是否可以打开进行写入不是一个选项。无论其他进程是否具有写访问权限,它都将始终失败。

正如Hans Passant和Igor Tandetnik所说,您只需将适当的共享标志传递给
CreateFile
。正如的MSDN文档所述:

文件共享\u写入0x00000002

启用文件或设备上的后续打开操作以请求写入访问权限

否则,如果其他进程请求写访问权限,则无法打开文件或设备

如果未指定此标志,但文件或设备已打开以进行写访问 或者具有写访问权限的文件映射,则功能失败。

您将希望使用如下代码:

HANDLE handle = CreateFile(name, GENERIC_READ, FILE_SHARE_READ, NULL,
                           OPEN_EXISTING, 0, NULL);
if (handle == INVALID_HANDLE_VALUE) {
    DWORD errcode = GetLastError();
    if (errcode == ERROR_SHARING_VIOLATION) {
        printf("%s: sharing violation\n", name);
    } else {
        printf("%s: CreateFile failed, error code = %lu\n", name, errcode);
    }
} else {
    printf("%s: CreateFile succeeded\n", name);
}

中的此代码无法判断发生
错误\u共享\u冲突
,是因为另一个进程打开文件进行写入,还是因为另一个进程在打开文件时未使用
文件\u共享\u读取
。在后一种情况下,任何读取文件的尝试都将因共享冲突而失败。传递
FILE\u SHARE\u READ
标志,以防止在文件已打开且使用
FILE\u SHARE\u READ
的情况下发生共享冲突。您还可以添加<代码> FielySyryDelaby,但我假定您会认为与Access Access相同。

您只需要显式指定文件共享。如果使用CreateFile(),则为dwShareMode参数传递0以获得独占访问权。如果使用_fsopen(),则传递_SH_DENYRW。如果您使用像fopen()这样的遗留C函数,那么请停止使用它,因为它不适合此工作。@HansPassant:谢谢您的回答,我可能会在我的代码中使用它!然而,我有点担心,如果其他进程只是读取文件,您的建议会产生错误的结果。此外,使用此测试将阻止其他进程读取该文件。后者只是一个小问题,因为我会在
CreateFile()之后立即调用
CloseHandle()
。但我还是对一个不那么打扰人的地方感兴趣test@HansPassant:抱歉,我刚刚实现了您的建议,但它似乎不起作用:如果一个进程具有写访问权限,那么另一个进程仍然可以
创建文件(名称,通用\u读取,0/*dwShareMode*/,0,打开现有,…)
。奇怪!不能复制。如果我
CreateFile
首先使用
GENERIC\u WRITE
甚至是最允许的共享模式
FILE\u SHARE\u READ | FILE\u SHARE\u WRITE
,然后尝试
CreateFile
再次使用
GENERIC\u READ
0
进行共享模式,第二次调用将失败。@Hanpassant,Igor Tandetnik:非常抱歉!在我被黑客攻击的原型中,我检查了
CreateFile()
的返回值是否为0,而不是
无效的句柄值。所以这个建议确实有效!但是,我仍然希望看到一种解决方案,它只排除编写器,但允许读者。刚刚尝试了您的解决方案,但似乎不起作用:因为dsDesiredAccess设置为0的CreateFile()始终成功。我假设已处理的写入调用:
CreateFileA(name,GENERIC_WRITE,0,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL)
。然后使用
dwDesiredAccess=0
运行代码会错误地返回有效句柄。设置
dwDesiredAccess=GENERIC_READ
dwShareMode=0
(Hans的建议)但当另一个进程通过
获得读取权限时,后者会给出误报:CreateFileA(名称、泛型读取、文件共享读取、NULL、打开现有、文件属性正常、NULL)
所以在你的
CreateFile
呼叫中传递
GENERIC\u READ
FILE\u SHARE\u READ
。谢谢你,罗斯,这就完成了!我已经更新了我的示例,使用
GENERIC\u READ
FILE\u SHARE\u READ