关闭文件后删除.xlsx或.pdf

时间:2019-05-23 11:00:32

标签: c# excel pdf process

我正尝试在使用它们后删除.xlsx或.pdf文件。创建文件时,我会显示它们,但是用户希望在关闭文件后自动删除文件。

我尝试了几件事,但似乎都无法正常工作。问题:

打开多个文件(.xlsx或.pdf)时,我无法终止单个进程,就像一个文件一样。相反,只有在我关闭所有相同的进程(Excel或PDF文件)时,该文件才会被删除。在我调查这种情况时,是因为Excel或PDF仅作为一个实例工作。但是,当我只打开一个文件时,代码可以按预期工作...

这是我到目前为止所拥有的:

 var process= Process.Start(file_path); //file_path is global variable
 Set_event(process);

 private void Set_event(Process process)
 {
        process.EnableRaisingEvents = true;
        process.Exited += new EventHandler(Delete_File);
 }

 public void Delete_File(object sender, EventArgs e)
 {
        //Delete file on close
        File.Delete(file_path);
 }

我还尝试了 FileOptions DeleteOnClose 方法,但是很遗憾,该方法不会向用户显示文件,并且在使用它们后并不会立即删除文件,仅在我的获胜应用程序关闭后。那不是我想要的输出,但是至少文件被删除了,所以如果我能解决的话,我也会部分满意。这是我的那句话:

   var open_file = new FileStream(file_path,FileMode.Open, FileAccess.ReadWrite,FileShare.ReadWrite, 512, FileOptions.DeleteOnClose);

话虽如此,我还有其他选择吗?预先感谢您的帮助。

1 个答案:

答案 0 :(得分:0)

我已经尝试了几乎所有可以找到的东西(Processed的Exited_Event的各种变体,使用FileSystemWatcher进行监视,使用DeleteOnClose-甚至API创建文件),但是它们都没有按预期工作。

一切都以我首先描述的问题结尾或失败-某些应用程序(例如Microsoft Excel或Adobe Acrobat)使用一个实例打开文件(.pdf或.xls / .xlsx),因此您不能仅引用打开更多文件时,将单个文件作为对象。这意味着您要么在尝试将Exited_event分配给单个文件时遇到错误,要么没有错误,但是仅当您关闭所有相同类型的文件时文件才会被删除...

足够幸运我发现了一件事:何时您打开了多个问题文件(.pdf或.xlsx),这在操作系统的后台发生了:如果您当时遍历相同类型的进程,则将获得正在使用的特定实例的列表。

换句话说,当您打开2个Excel文件时,“循环浏览”过程仅向您显示“ EXCEL”过程当前处于活动状态的文件。

因此,这使我想到了一种可以解决此问题的全新方法。为了对此有一个完整的解决方案,您必须:

1。。创建一种方法来检查文件是否不再使用。

2。。将计时器设置为2秒的延迟,以确保过程真正结束。也许应该出于不同目的将其增加...

3。。设置Timer_tick事件,在该事件中循环处理以查看特定文件是否被列为活动文件,以及用户是否已关闭该文件。正如其他用户所描述的那样,该方法不太准确,但是由于设置了Timer的延迟,我认为应该不再有任何问题了。

这是完整的代码(.pdf和.xlsx-这正是我所需要的):

   //as global variable
   System.Windows.Forms.Timer delete_file = new System.Windows.Forms.Timer(); 

    Process.Start(file_path); //file_path is global variable

    delete_file.Tick += new EventHandler(timer_Tick); 
    delete_file.Interval = (2000);              
    delete_file.Enabled = true;                     
    delete_file.Start();

    private void timer_Tick(object sender, EventArgs e)
    {
        Boolean file_is_opened = false;

        // Loop processes and list active files in use
        foreach (var process in Process.GetProcesses())
        {
          if (process.MainWindowTitle.Contains(Path.GetFileName(file_path)))
          {
             file_is_opened = true;
          }
        }

         //If our file is not listed under active processes we check 
         //whether user has already closed file - If so, we finally delete It
         if (file_is_opened==false)
         {
            if (!File_In_Use(new FileInfo(file_path)))
            {
                 File.Delete(file_path);
                 delete_file.Enabled = false;
                 delete_file.Stop();
                 return;
             }
          }
     }

     private bool File_In_Use(FileInfo file)
     {
         //Method to check whether file is in use

         FileStream stream = null;

         try
         {
              //If file doesn't exist
              if (!file.Exists)
              {
                     return false;
              }

              stream = file.Open(FileMode.Open, FileAccess.ReadWrite, FileShare.None);
         }
         catch (IOException)
         {
               //File is unavailable:
              //because someone writes to It, or It's being processed
              return true;
         }
         finally
         {
            if (stream!=null)
            {
              stream.Close();
            }
         }

             //File not locked
             return false;
      }

这就是我的做法。它可能不是一个完美的解决方案,但是对我来说,在Win 10上仍然可以正常使用。

如果有人建议修复较高的代码,请告诉我。否则,我希望这对以后的人有所帮助,因为我注意到过去已经对此有一些疑问,没有适当的答案。