2008-09-30 2 views
7

파일을 작성하고 닫은 다음 목적지 위치로 이동하는 것이 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_TEMPORARYFILE_ATTRIBUTE_NOT_CONTENT_INDEXED 플래그를 설정하여이 문제를 피할 수 있음을 알았습니다. FILE_ATTRIBUTE_NOT_CONTENT_INDEXED은 그 자체로 충분하지만 파일을 임시로 표시하면 검색 인덱서로 인해 디스크 작업이 크게 줄어 듭니다.

그러나 이것은 실제 솔루션이 아닙니다입니다. 내 말은, 응용 프로그램이 파일을 만들고 이름을 바꿀 수 있기를 기대할 수 없다면, 어떤 비스타의 검색 색인 작성자가 그것을 망쳐 놓고 있기 때문입니다. 그것은 완전히 미친 것입니다.! 다시 시도해야합니까? 사용자에게 소리를 지르며 (이는 매우 바람직하지 않음)? 다른 것을 해보시겠습니까?

+0

Vista SP1 (즉, SP1 또는 WinXP없이)에서만 발생합니까? 일반적으로 반복 횟수는 얼마나됩니까? –

답변

4

Process Monitor(편집 : 이전에 FileMon으로 알려진)을 사용하여 정확히 어떤 응용 프로그램이 진행되고 있는지 확인하는 것이 좋습니다. 그것은 당신에게 당신의 컴퓨터에서 만들어진 파일 시스템 호출의 전체 추적을 보여줄 수 있습니다.

:

+0

Filemon은 훌륭한 도구입니다 (저는 거의 매일 직장에서 사용하고 있습니다).하지만 프로세스 모니터로 대체되었습니다 - URL http://technet.microsoft.com/en-us/sysinternals/bb896645.aspx - FileMon과 RegMon의 기능을 모두 포함합니다. –

1

나는 당신의 안티 바이러스 또는 Windows 인덱싱이 동시에 파일을 망쳐 놓는다 고 말하고 싶습니다. 안티 바이러스없이 동일한 테스트를 실행할 수 있습니까? 그런 다음 다시 실행하여 임시 파일이 Windows 검색에 의해 색인이 생성되지 않은 어딘가에 만들어 졌는지 확인하십시오.

+0

실행중인 바이러스 백신이 없습니다. Windows 검색을 사용하지 않도록 설정해 보겠습니다. – NeARAZ

0

일반적으로 문제의 파일에 열린 핸들이 있거나 실행중인 바이러스 스캐너가 실행 중일 수 있습니다. Sysinternals 사이트에서 Process Monitor와 같은 것을 실행 해 보셨습니까? 모든 파일 작업을 필터링하고 후드 아래에서 진행되는 작업을보다 잘 파악해야합니다.

0

윈도우 응용 프로그램 파일을 저장하기위한 특별한 위치를 가지고 있으며, 나는 그것의 색인 생각하지 않는다 (적어도 기본적으로) (편집 덕분에 응용 프로그램에서 변경 @moocha합니다). Vista의 경로는 다음과 같습니다

C : I 제안 \ 사용자 \의 AppData

사용자 이름 \이 응용 프로그램에 적합한 경우이 파일을 넣어.

+1

아니, 내 상황에 맞지 않습니다. 또한 원래 문제에 대한 답변을 제공하지 않습니다. 도크 파일 인덱서가 액세스를 거부 한 결과는 무엇입니까? 인덱서와 같은 백그라운드 프로세스는 결코 그런 상황을 만들어 내지 못합니다. – NeARAZ