파일을 작성하고 닫은 다음 목적지 위치로 이동하는 것이 Vista에서는 임의로 실패합니다. 특히 MoveFileEx()는 명백한 이유없이 ERROR_ACCESS_DENIED
을 반환합니다. 이것은 Vista SP1에서 최소한 (32 비트) 발생합니다. XP SP3에서는 발생하지 않습니다.Vista에서 무작위 MoveFileEx 실패
실제 해결책이없는 완전히 동일한 문제에 대해 인터넷에 this thread이 발견되었습니다. 지금까지는 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;
}
Visual Studio에서 콘솔 앱으로 빌드하십시오. 올바른 동작은 테스트 번호를 인쇄하는 무한 루프입니다. Vista SP1에서 프로그램은 임의의 반복 횟수 후에 종료됩니다 (일반적으로 100 회 반복하기 전에).
Windows XP SP2에서는 발생하지 않습니다. 바이러스 백신이 전혀 실행되지 않습니다. 그리고 다른 이상한 백그라운드 프로세스 (컴퓨터는 꽤 바닐라 OS 설치 + 비주얼 스튜디오).
편집 : 프로세스 모니터 (감사 @sixlettervariables)를 통해 추가로 파고를하면 특히 나쁜 것을 볼 수 없습니다. 각 테스트 반복은 176 개의 디스크 작업으로 이루어지며 대부분이 SearchProtocolHost.exe (검색 인덱서)에서 제공됩니다. 검색 색인 서비스가 중지되면 오류가 발생하지 않으므로 문제가 발생한 것으로 보입니다.
SearchProtocolHost.exe는 앱이 ERROR_ACCESS_DENIED
일 때 읽기/쓰기/삭제 공유 모드로 열리는 디 터미네이션 파일 (bbb)에 두 개의 CreateFile이 있으므로 확인해야합니다. 열기 중 하나에 기회주의 자물쇠 (FSCTL_REQUEST_FILTER_OPLOCK
)가 표시 될 수 있습니다. 그 원인 일 수 있습니까?
어쨌든, 나는 파일에 FILE_ATTRIBUTE_TEMPORARY
및 FILE_ATTRIBUTE_NOT_CONTENT_INDEXED
플래그를 설정하여이 문제를 피할 수 있음을 알았습니다. FILE_ATTRIBUTE_NOT_CONTENT_INDEXED
은 그 자체로 충분하지만 파일을 임시로 표시하면 검색 인덱서로 인해 디스크 작업이 크게 줄어 듭니다.
그러나 이것은 실제 솔루션이 아닙니다입니다. 내 말은, 응용 프로그램이 파일을 만들고 이름을 바꿀 수 있기를 기대할 수 없다면, 어떤 비스타의 검색 색인 작성자가 그것을 망쳐 놓고 있기 때문입니다. 그것은 완전히 미친 것입니다.! 다시 시도해야합니까? 사용자에게 소리를 지르며 (이는 매우 바람직하지 않음)? 다른 것을 해보시겠습니까?
Vista SP1 (즉, SP1 또는 WinXP없이)에서만 발생합니까? 일반적으로 반복 횟수는 얼마나됩니까? –