Как удалить файл, который открыл дескрипторы? - PullRequest
4 голосов
/ 21 сентября 2010

ИСТОРИЯ ПРОБЛЕМЫ:
Теперь я использую Windows Media Player SDK 9 для воспроизведения файлов AVI в настольном приложении.Он хорошо работает в Windows XP, но когда я пытаюсь запустить его в Windows 7 , я обнаружил ошибку - Я не могу удалить файл AVI сразу после воспроизведения .Проблема в том, что существуют открытые файловые дескрипторы.В Windows XP у меня есть 2 открытых дескриптора файла во время воспроизведения файла, и они закрываются после закрытия окна воспроизведения, но в Windows 7 у меня уже есть 4 открытых дескриптора во время воспроизведения файла, и 2 из них остаются после закрытия окна воспроизведения.Они становятся бесплатными только после закрытия приложения.

ВОПРОС:
Как я могу решить эту проблему? Как удалить файл, который открыл дескрипторы? Может быть, существует что-то вроде "принудительного удаления"?

Ответы [ 4 ]

3 голосов
/ 04 января 2011

Проблема в том, что вы не единственный, кто получает дескрипторы вашего файла.Другие процессы и службы также могут открыть файл.Таким образом, удаление невозможно, пока они не освободят свои ручки.Вы можете переименовать файл, когда эти дескрипторы открыты.Вы можете скопировать файл, когда эти ручки открыты.Однако не уверены, что вы можете переместить файл в другой контейнер?

Другие процессы и службы esp.включая антивирус, индексацию и т. д.

Вот функция, которую я написал для выполнения «немедленного удаления» в Windows:

bool DeleteFileNow(const wchar_t * filename)
{
    // don't do anything if the file doesn't exist!
    if (!PathFileExistsW(filename))
        return false;

    // determine the path in which to store the temp filename
    wchar_t path[MAX_PATH];
    wcscpy_s(path, filename);
    PathRemoveFileSpecW(path);

    // generate a guaranteed to be unique temporary filename to house the pending delete
    wchar_t tempname[MAX_PATH];
    if (!GetTempFileNameW(path, L".xX", 0, tempname))
        return false;

    // move the real file to the dummy filename
    if (!MoveFileExW(filename, tempname, MOVEFILE_REPLACE_EXISTING))
    {
        // clean up the temp file
        DeleteFileW(tempname);
        return false;
    }

    // queue the deletion (the OS will delete it when all handles (ours or other processes) close)
    return DeleteFileW(tempname) != FALSE;
}
1 голос
/ 04 января 2011

Технически вы можете удалить заблокированный файл, используя MoveFileEx и передав MOVEFILE_DELAY_UNTIL_REBOOT. Когда параметр lpNewFileName равен NULL, Move превращается в удаление и может удалить заблокированный файл. Однако это предназначено для установщиков и, помимо прочего, требует прав администратора.

0 голосов
/ 04 января 2011

Вы уже пытались попросить WMP вместо этого освободить дескрипторы? ( IWMPCore :: close , кажется, делает это)

0 голосов
/ 04 января 2011

Вы проверили, какое приложение все еще использует файл avi? Вы можете сделать это, используя handle.exe . Вы можете попробовать удалить / переместить файл после закрытия процесса (ов), который / он использует этот файл.

Альтернативным решением будет использование приложения unlocker (бесплатно).

Один из двух приведенных выше способов должен решить вашу проблему.

...