Как удалить файл, если приложение не запущено? - PullRequest
1 голос
/ 06 апреля 2011

Не уверен, возможно ли это, но я создаю приложение для кодирования файлов. Когда файл декодируется, он временно сохраняется во временном каталоге, после чего его можно регулярно открывать. Однако на самом деле я должен быть уверен, что файл будет удален, как только приложение, которое его открыло, закрыло (например, закрылось). В противном случае декодированный (секретный) файл просто висит в каталоге temp без присмотра.

Более того, даже если само приложение по какой-либо причине было закрыто, я бы хотел передать эту задачу Windows, если это возможно. Допустим, пользователь декодирует файл и открывает его, а затем мое приложение закрывается (нормально или ненормально), декодированный файл из временного каталога должен быть удален, как только он больше не используется.

Как бы я поступил об этом? Я видел такие подсказки, как FileSystemWatcher и тривиальную идею «проверяй каждую секунду», но если мое приложение не работает в момент закрытия декодированного файла, я все равно хотел бы удалить его. Поэтому я думаю, что мне нужно передать эту ответственность Windows, но я не уверен, возможно ли это, и если да, то как.

Итак, как мне удалить файл, как только он закроется, если мое приложение не запускается в данный момент?

Ответы [ 3 ]

2 голосов
/ 06 апреля 2011

Это может сработать:

  1. В процессе, который создает файл, создайте его с помощью FileOptions.DeleteOnClose и FileShare.ReadWrite (или FileShare.Read, если для других процессов требуется только доступ на чтение). Вам также может понадобиться FileShare.Delete.
  2. НЕ позволяйте файлу закрываться в главном приложении, которое его создало, до тех пор, пока приложение не закроется.
  3. В других процессах, которые используют временный файл, откройте его с теми же параметрами файла, что и у исходного.

Таким образом, когда последний процесс с открытым файлом закрывается, файл будет удален.

UPDATE:

Как отмечается в комментариях, в API .NET, похоже, нет способа указать обе опции FIleShare и FileOptions.DeleteOnClose. Это возможно с помощью прямой Win32. Я скопировал образец, который я тестировал ниже. Есть 2 программы, одна создает файл, другая использует его. Единственное заметное различие между этими двумя параметрами заключается в том, что потребитель открывает файл с помощью OPEN_EXISTING.

Creator

#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <iostream>
#include <string>

int _tmain(int argc, _TCHAR* argv[])
{
    HANDLE fh = CreateFile(
        L"yourFilePath\\tempFile.dat",
        GENERIC_READ | GENERIC_WRITE,
        FILE_SHARE_WRITE|FILE_SHARE_READ|FILE_SHARE_DELETE,
        NULL,
        CREATE_NEW,
        FILE_FLAG_DELETE_ON_CLOSE,
        NULL);
    if(fh==INVALID_HANDLE_VALUE)
    {
        std::cerr << "Failed to create file. Error code = " << GetLastError() << std::endl;
        return 1;
    }

    std::cout<< "Hit enter to close.";
    std::string inp;
    std::getline(std::cin,inp);

    CloseHandle(fh);


    return 0;
}

Потребитель

#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <iostream>
#include <string>

int _tmain(int argc, _TCHAR* argv[])
{
    HANDLE fh = CreateFile(
        L"yourFilePath\\tempFile.dat",
        GENERIC_READ | GENERIC_WRITE,
        FILE_SHARE_WRITE|FILE_SHARE_READ|FILE_SHARE_DELETE,
        NULL,
        OPEN_EXISTING,
        FILE_FLAG_DELETE_ON_CLOSE,
        NULL);
    if(fh==INVALID_HANDLE_VALUE)
    {
        std::cerr << "Failed to create file. Error code = " << GetLastError() << std::endl;
        return 1;
    }

    DWORD written;
    if(!WriteFile(fh,"Test",4,&written,NULL))
    {
        std::cerr << "Failed to write data to file. Error code = " << GetLastError() << std::endl;
        return 1;
    }


    std::cout<< "Hit enter to close.";
    std::string inp;
    std::getline(std::cin,inp);

    CloseHandle(fh);


    return 0;
}
1 голос
/ 06 апреля 2011

Использовать FileOptions.DeleteOnClose.

0 голосов
/ 06 апреля 2011

Такие вещи, как FileOptions.DeleteOnClose, не помогут, если ваш носитель станет недоступным или аппарат выключится до того, как произойдет удаление.Для меня это очень похоже на экзогенное состояние .

Можете ли вы транслировать декодирование в поток памяти, а не на диск, и устранить всю проблему.

...