【问题标题】:When terminating a process is it possible to delete a file?终止进程时是否可以删除文件?
【发布时间】:2014-06-27 09:30:36
【问题描述】:

我需要编写一个 Windows C 应用程序来创建一个文件,并且在应用程序终止时需要删除该文件(无论是正常终止还是强制终止)。 p>

另一个要求是用户还应该能够以只读模式打开此文件(可能使用记事本)。基本上这将在 Java 中读取(即 DocumentBuilder::parse)

我写了以下代码

   HANDLE hFile = CreateFile("d:\\test.xml",                
                   GENERIC_WRITE,          
                   FILE_SHARE_READ,                      
                   NULL,                   
                   CREATE_ALWAYS,             
                   FILE_FLAG_DELETE_ON_CLOSE,  
                   NULL);  

当我在 Notepad.exe 中打开文件(即 test.xml)时,我收到一条错误消息“该进程无法访问该文件,因为它正被另一个进程使用”。

但是,以下代码可以正常工作

   HANDLE hFile = CreateFile("d:\\test.xml",                
                   GENERIC_WRITE,          
                   FILE_SHARE_READ,                      
                   NULL,                   
                   CREATE_ALWAYS,             
                   FILE_ATTRIBUTE_NORMAL,
                   NULL);                

但问题是,它不会删除文件(即当应用程序被杀死时)。

感谢任何帮助。

如果您可以建议一种适用于 Windows 和 Unix 的方法,那就太好了(例如,使用 boost 库)。

【问题讨论】:

  • 您说您正在编写一个 C 应用程序,但您的问题被标记为 C++。澄清。
  • 创建文件。关闭它。使用所需的标志再次打开它。至于在进程强制终止时删除文件,(任务管理器或kill -9),是做不到的。你不能在进程启动时删除文件吗?

标签: c windows file-io


【解决方案1】:

documentation 说:

文件将在其所有句柄被删除后立即删除 关闭,其中包括指定的句柄和任何其他打开或 重复的句柄。

如果文件存在现有的打开句柄,则调用失败,除非 它们都是以 FILE_SHARE_DELETE 共享模式打开的。

文件的后续打开请求失败,除非 指定了 FILE_SHARE_DELETE 共享模式。

因此,您需要安排任何打开文件的进程传递FILE_SHARE_DELETE

【讨论】:

    【解决方案2】:

    这是来自我们的代码库:(other answer 有文档链接)

    FILE_FLAG_DELETE_ON_CLOSE 也将阻止读者,除非他们指定 FILE_SHARE_DELETE

    return ::CreateFile(
        filePath, 
        GENERIC_READ | GENERIC_WRITE, // reading and writing
        FILE_SHARE_READ, // Note: FILE_FLAG_DELETE_ON_CLOSE will also block readers, unless they specify FILE_SHARE_DELETE 
        /*Security:*/NULL, 
        CREATE_NEW, // only create if does not exist
        FILE_ATTRIBUTE_TEMPORARY | // optimize access for temporary file
        FILE_FLAG_DELETE_ON_CLOSE, // delete once the last handle has been closed
        NULL);
    

    看来您对标准应用程序不走运(*),因为(根据我过去的智慧)读者还需要通过FILE_SHARE_DELETE


    (*) 大多数文件在文本编辑器中打开时都可以删除,但我相信这是因为这些编辑器在读取内容后会简单地关闭文件句柄。如果他们提供FILE_SHARE_DELETE 模式,您可以查看流行的免费模式。

    【讨论】:

      【解决方案3】:

      您可以检查此文件的访问级别: if(!_tacces(path, 06) //exit application.

      关于 _tacces 的更多信息:http://msdn.microsoft.com/en-us/library/1w06ktdy.aspx

      【讨论】:

        【解决方案4】:

        您可以创建一个辅助进程来跟踪主进程句柄,并在(任何)主进程终止时尝试删除文件。如果文件以非共享方式(由记事本或其他人)打开,则这两种方式都可能无法完成。

        【讨论】:

          猜你喜欢
          • 2022-01-19
          • 1970-01-01
          • 2018-09-30
          • 2019-09-29
          • 1970-01-01
          • 1970-01-01
          • 2010-10-03
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多