انتهاك مشاركة إذن ملف Win32 أثناء حذف ملف مؤقت

StackOverflow https://stackoverflow.com/questions/1424579

  •  07-07-2019
  •  | 
  •  

سؤال

لدي تطبيق حيث أحاول تنفيذ "الكتابة فوق الملف الآمن" عن طريق:

  1. إنشاء ملف (A)
  2. حشوة A مع البيانات
  3. النسخ A إلى وجهتها النهائية (B) عبر SHFileOperation
  4. حذف A استخدام DeleteFile

ولكن في الخطوة 4 DeleteFile تُرجع دائمًا ERROR_SHARING_VIOLATION.تستغرق العملية برمتها ميلي ثانية، لذلك لا أستطيع أن أتخيل من سيتدخل في ملفي.بضعة أسئلة:

  1. هل هناك تقنية Win32 (C/C++) أفضل لتنفيذ ما ورد أعلاه؟
  2. كيف يمكنني الحصول على مزيد من المعلومات حول "العملية الأخرى" التي تمنعني من حذف الملف A?
  3. كيف بلطف (غمزة غمزة دفعة) إجبار 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));
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top