पर यादृच्छिक MoveFileEx विफलताओं मैंने देखा कि फ़ाइल को लिखना, इसे बंद करना और गंतव्य स्थान पर ले जाना, Vista पर यादृच्छिक रूप से विफल रहता है। विशेष रूप से, MoveFileEx() किसी स्पष्ट कारण के लिए ERROR_ACCESS_DENIED
वापस कर देगा। यह Vista Vista SP1 कम से कम (32 बिट) पर होता है। एक्सपी एसपी 3 पर नहीं होता है।Vista
कोई वास्तविक समाधान के साथ, बिल्कुल उसी समस्या के बारे में internets पर 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;
}
इसे विजुअल स्टूडियो के साथ कंसोल ऐप के रूप में बनाएं। सही व्यवहार अनंत लूप होगा जो परीक्षण संख्या प्रिंट करता है। विस्टा एसपी 1 पर, कार्यक्रम यादृच्छिक संख्या यादृच्छिक संख्या के बाद निकलता है (आमतौर पर 100 पुनरावृत्तियों से पहले)।
यह Windows XP SP2 पर नहीं होता है। कोई एंटीवायरस बिल्कुल चल रहा है; और कोई अन्य अजीब पृष्ठभूमि प्रक्रिया नहीं है (मशीन काफी ज्यादा वेनिला ओएस इंस्टॉल + विजुअल स्टूडियो है)।
संपादित करें: प्रोसेस मॉनिटर (धन्यवाद @ सिक्सलेटवारीबल्स) के माध्यम से आगे बढ़ना, मैं कुछ भी विशेष रूप से खराब नहीं देख सकता। प्रत्येक टेस्ट पुनरावृत्ति के परिणामस्वरूप 176 डिस्क ऑपरेशंस होते हैं, उनमें से अधिकतर SearchProtocolHost.exe (खोज अनुक्रमणिका) से आते हैं। यदि खोज अनुक्रमणिका सेवा बंद है, तो कोई त्रुटि नहीं होती है, इसलिए ऐसा लगता है कि यह अपराधी है।
विफलता के समय (जब ऐप ERROR_ACCESS_DENIED
प्राप्त होता है), SearchProtocolHost.exe में दो संपादन फ़ाइल (बीबीबी) को पढ़ने/लिखने/साझा करने के तरीके के साथ खुले फ़ाइल फ़ाइल (बीबीबी) है, तो यह ठीक होना चाहिए। खुले में से एक अवसरवादी लॉक (FSCTL_REQUEST_FILTER_OPLOCK
) के बाद होता है, शायद यही कारण है?
वैसे भी, मुझे पता चला कि मैं फ़ाइल पर FILE_ATTRIBUTE_TEMPORARY
और FILE_ATTRIBUTE_NOT_CONTENT_INDEXED
फ़्लैग सेट करके समस्या से बच सकता हूं। ऐसा लगता है कि FILE_ATTRIBUTE_NOT_CONTENT_INDEXED
अपने आप से पर्याप्त है, लेकिन फ़ाइल को अस्थायी रूप से चिह्नित करने से भी खोज सूचकांक के कारण डिस्क संचालन में नाटकीय रूप से कटौती होती है।
लेकिन यह वास्तविक समाधान नहीं है। मेरा मतलब है, यदि कोई एप्लिकेशन फ़ाइल बनाने में सक्षम होने की उम्मीद नहीं कर सकता है और इसका नाम बदल सकता है क्योंकि कुछ Vista की खोज अनुक्रमणिका इसके साथ गड़बड़ कर रही है, यह पूरी तरह से पागल है! क्या इसे पुनः प्रयास करना चाहिए? उपयोगकर्ता पर येल (जो बहुत अवांछनीय है)? कुछ और करो?
क्या यह केवल Vista SP1 (यानी, SP1 के बिना या WinXP पर) होता है? यह आमतौर पर कितने पुनरावृत्तियों लेता है? –