Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/132.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
C++ Vista上的随机MoveFileEx失败_C++_Windows_Winapi_Windows Vista - Fatal编程技术网

C++ Vista上的随机MoveFileEx失败

C++ Vista上的随机MoveFileEx失败,c++,windows,winapi,windows-vista,C++,Windows,Winapi,Windows Vista,我注意到,在Vista上,写入文件、关闭文件并将其移动到目标位置会随机失败。具体地说,MoveFileEx()将返回错误\u访问\u被拒绝,没有明显的原因。这至少发生在Vista SP1上(32位)。不会发生在XP SP3上 在互联网上发现了完全相同的问题,没有真正的解决方案。到目前为止,该错误似乎是由Vista的搜索索引器引起的,请参见下文 这里给出的代码示例足以重现该问题。我也将其粘贴到这里: #include <windows.h> #include <stdlib.h&

我注意到,在Vista上,写入文件、关闭文件并将其移动到目标位置会随机失败。具体地说,MoveFileEx()将返回
错误\u访问\u被拒绝
,没有明显的原因。这至少发生在Vista SP1上(32位)。不会发生在XP SP3上

在互联网上发现了完全相同的问题,没有真正的解决方案。到目前为止,该错误似乎是由Vista的搜索索引器引起的,请参见下文

这里给出的代码示例足以重现该问题。我也将其粘贴到这里:

#include <windows.h>
#include <stdlib.h> 
#include <stdio.h> 

bool test() {
    unsigned char buf[] = {
        0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 
        0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99 
    }; 
    HANDLE h; 
    DWORD nbytes; 
    LPCTSTR fn_tmp = "aaa"; 
    LPCTSTR fn = "bbb"; 
    h = CreateFile(fn_tmp, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_ALWAYS, 0, 0); 
    if (h == INVALID_HANDLE_VALUE) return 0; 
    if (!WriteFile(h, buf, sizeof buf, &nbytes, 0)) goto error; 
    if (!FlushFileBuffers(h)) goto error; 
    if (!CloseHandle(h)) goto error; 
    if (!MoveFileEx(fn_tmp, fn, MOVEFILE_REPLACE_EXISTING | MOVEFILE_COPY_ALLOWED | MOVEFILE_WRITE_THROUGH)) { 
        printf("error=%d\n", GetLastError()); 
        return 0; 
    } 
    return 1; 
error: 
    CloseHandle(h); 
    return 0; 
} 

int main(int argc, char** argv) { 
    unsigned int i; 
    for (i = 0;; ++i) { 
        printf("*%u\n", i); 
        if (!test()) return 1; 
    } 
    return 0; 
}
#包括
#包括
#包括
布尔测试{
无符号字符buf[]={
0x00、0x11、0x22、0x33、0x44、0x55、0x66、0x77、0x88、0x99,
0x00、0x11、0x22、0x33、0x44、0x55、0x66、0x77、0x88、0x99
}; 
手柄h;
德沃德单位;
LPCTSTR fn_tmp=“aaa”;
LPCTSTR fn=“bbb”;
h=CreateFile(fn_tmp,GENERIC_WRITE,FILE_SHARE_READ,FILE_SHARE_WRITE,0,OPEN_ALWAYS,0,0);
if(h==无效的\u句柄\u值)返回0;
如果(!WriteFile(h,buf,sizeof buf,&nbytes,0))转到错误;
如果(!FlushFileBuffers(h))转到错误;
如果(!CloseHandle(h))转到错误;
如果(!MoveFileEx(fn_tmp,fn,MOVEFILE_REPLACE_现有| MOVEFILE_COPY_允许| MOVEFILE_WRITE_THROUGH)){
printf(“错误=%d\n”,GetLastError());
返回0;
} 
返回1;
错误:
闭合手柄(h);
返回0;
} 
intmain(intargc,字符**argv){
无符号整数i;
对于(i=0;;++i){
printf(“*%u\n”,i);
如果(!test())返回1;
} 
返回0;
}
使用Visual Studio将此构建为控制台应用程序。正确的行为应该是打印测试编号的无限循环。在Vista SP1上,程序在随机迭代次数后退出(通常在进行100次迭代之前)

这在Windows XP SP2上不会发生。根本没有防病毒软件在运行;并且没有其他奇怪的后台进程(机器几乎是香草操作系统安装+Visual Studio)

编辑:通过过程监视器进一步挖掘(感谢@sixlettvariables),我看不到任何特别糟糕的东西。每次测试迭代都会产生176个磁盘操作,其中大部分来自SearchProtocolHost.exe(搜索索引器)。如果搜索索引服务停止,则不会发生错误,因此看起来这是罪魁祸首

出现故障时(当应用程序出现
错误\u访问\u被拒绝时
),SearchProtocolHost.exe有两个指向以读/写/删除共享模式打开的指定文件(bbb)的CreateFile,因此应该可以。其中一个打开之后是机会主义锁(
FSCTL\u REQUEST\u FILTER\u OPLOCK
),这可能是原因吗

无论如何,我发现通过在文件上设置
FILE\u ATTRIBUTE\u TEMPORARY
FILE\u ATTRIBUTE\u NOT\u CONTENT\u index
标志可以避免这个问题。看起来
FILE\u ATTRIBUTE\u NOT\u CONTENT\u index
本身就足够了,但将文件标记为临时文件也可以显著减少搜索索引器导致的磁盘操作


但这不是真正的解决方案。我的意思是,如果一个应用程序无法创建一个文件并重命名它,因为一些Vista的搜索索引器正在处理它,这太疯狂了!它应该继续重试吗?对用户大喊大叫(这是非常不受欢迎的)?做点别的吗?

我想说的是,要么是你的防病毒软件,要么是Windows索引在同一时刻弄乱了文件。你能在没有防病毒的情况下运行相同的测试吗。然后再次运行它,确保临时文件是在未被Windows Search索引的位置创建的?

这通常意味着其他文件的句柄已打开,可能是正在运行的活动病毒扫描程序?您是否尝试过从站点运行类似Process Monitor的程序?你应该对所有文件操作进行过滤,更好地了解引擎盖下正在发生的事情。

我建议你使用(编辑:艺术家,以前称为FileMon)来观察并查看到底是哪个应用程序在妨碍你。它可以向您显示在您的计算机上进行的文件系统调用的整个跟踪


(编辑:感谢@moocha对应用程序的更改)

Windows有一个存储应用程序文件的特殊位置,我认为它没有索引(至少默认情况下没有)。在Vista中,路径为:

C:\Users\user name\AppData


如果适合您的应用程序,我建议您将文件放在那里。

这种情况是否只发生在Vista SP1上(即,没有SP1或在WinXP上)?通常需要多少次迭代?Filemon是一个很棒的工具(我几乎每天都在工作中使用它)-但它已被Process Monitor-URL-所取代,它包含Filemon和RegMon的功能。没有运行防病毒程序。我将尝试禁用windows搜索。不,这不适合我的情况。此外,它也没有回答最初的问题-heck文件索引器正在做什么导致拒绝访问错误?像indexer这样的后台进程永远不应该创建这样的情况。