انتهاك مشاركة إذن ملف Win32 أثناء حذف ملف مؤقت
-
07-07-2019 - |
سؤال
لدي تطبيق حيث أحاول تنفيذ "الكتابة فوق الملف الآمن" عن طريق:
- إنشاء ملف (
A
) - حشوة
A
مع البيانات - النسخ
A
إلى وجهتها النهائية (B
) عبرSHFileOperation
- حذف
A
استخدامDeleteFile
ولكن في الخطوة 4 DeleteFile
تُرجع دائمًا ERROR_SHARING_VIOLATION.تستغرق العملية برمتها ميلي ثانية، لذلك لا أستطيع أن أتخيل من سيتدخل في ملفي.بضعة أسئلة:
- هل هناك تقنية Win32 (C/C++) أفضل لتنفيذ ما ورد أعلاه؟
- كيف يمكنني الحصول على مزيد من المعلومات حول "العملية الأخرى" التي تمنعني من حذف الملف
A
? - كيف بلطف (غمزة غمزة دفعة) إجبار Windows على حذف ملفي المؤقت؟
أي اقتراحات أخرى هي موضع ترحيب
المحلول
أفضل تخميني هو أنك تحتاج إلى الخطوة 2.5) أغلق مقبض الملف الذي تم إنشاؤه في 1)
ما الذي تستخدمه لإنشاء/فتح الملف؟
إذا كنت تستخدم CreateFile، فتأكد من إغلاق مقبض الملف الخاص بك قبل استدعاء الحذف، أو تأكد من تحديد علامة المشاركة FILE_SHARE_DELETE
.
HANDLE hFile = CreateFile("C:\\test.txt", GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, CREATE_ALWAYS, 0, NULL);
قد ترغب أيضًا في تبسيط عملية نسخ رمز الملف باستخدام Win32 API نسخة ارشيف.
نصائح أخرى
إحدى طرق حذف الملف هي فتحه باستخدام FILE_FLAG_DELETE_ON_CLOSE
والذي سيطلب من نظام التشغيل حذف الملف تلقائيًا بعد إغلاق المؤشر الأخير له.إذا قمت بإنشاء الملف باستخدام FILE_SHARE_READ
ثم SHFileOperation
يجب أن تكون قادرًا على قراءته لنسخه، ويمكنك بعد ذلك إغلاق المقبض الخاص بك على الملف على الفور.عندما تغلق القشرة إنه التعامل مع الملف، سيتم حذف الملف تلقائيا.
حاول استخدام Handles.exe من www.sysinternals.com لمعرفة ما إذا كان الملف قيد الاستخدام وكيفية استخدامه.
يمكنك استخدام GetLastError وFormatMessage للحصول على مزيد من المعلومات حول آخر وظيفة فاشلة:
بعض نماذج التعليمات البرمجية:
char tx2[1024];
DWORD l;
if(l = GetLastError())
{
LPVOID lpMessageBuffer = 0;
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
NULL,
l,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), //The user default language
(LPTSTR) &lpMessageBuffer,
0,
NULL
);
SetLastError(0);
MessageBox(NULL, tx2, "MyApplication", MB_ICONINFORMATION | MB_OK | (MB_SETFOREGROUND | MB_TOPMOST | MB_TASKMODAL));
}