Нарушение прав доступа к файлу Win32 при удалении временного файла - PullRequest
2 голосов
/ 15 сентября 2009

У меня есть приложение, в котором я пытаюсь реализовать «безопасную перезапись файла»:

  1. Создание файла (A)
  2. Заполнение A данными
  3. Копирование A в конечный пункт назначения (B) с помощью SHFileOperation
  4. Удаление A с использованием DeleteFile

Однако на шаге 4 DeleteFile всегда возвращает ERROR_SHARING_VIOLATION. Весь процесс занимает миллисекунды, поэтому я не могу себе представить, кто еще будет мешать моему файлу. Пара вопросов:

  1. Есть ли лучший метод Win32 (C / C ++) для выполнения вышеуказанного?
  2. Как я могу получить больше информации о "другом процессе", который мешает мне удалить файл A?
  3. Как мне аккуратно ( подмигнуть, подтолкнуть подтолкнуть ) заставить Windows удалить мой временный файл?

Любые другие предложения приветствуются

Ответы [ 3 ]

5 голосов
/ 15 сентября 2009

Мое лучшее предположение: шаг 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 CopyFile .

1 голос
/ 15 сентября 2009

Один из способов удаления файла - открыть его с помощью FILE_FLAG_DELETE_ON_CLOSE, который попросит ОС автоматически удалить файл после закрытия последнего дескриптора к нему. Если вы создадите файл с помощью FILE_SHARE_READ, тогда SHFileOperation сможет прочитать его, чтобы скопировать, и вы сможете сразу же закрыть свой дескриптор файла. Когда оболочка закрывает свой дескриптор для файла, файл будет автоматически удален.

0 голосов
/ 15 сентября 2009
  • Попробуйте использовать файл 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));
}
...