Tronald
Tronald

Reputation: 1585

Create and open as read-only a temporary copy of an existing file and delete after use

I've scoured for information, but I just fear I may be getting in over my head here as I am not proficient in multi-threading. I have desktop app that needs to create a read-only, temp copy of an existing file, open the file in it's default application and then delete the file once the user is done viewing it.

It must open read only as the user may try and save it thinking it's the original file.

To do this I have created a new thread which copies the file to a temp path, set's the files attributes, attaches a Process handler to it and then "waits" and deletes the file on exit. The advantage of this is that the thread will continue to run even after the program has exited (so it seems anyway). This way the file will still delete even if the user keeps it open longer than the program.

Here is my code. The att object holds my file information.

new Thread(() =>
{
      //Create the temp file name
      string temp = System.IO.Path.GetTempPath() + att.FileNameWithExtension;

      //Determine if this file already exists (in case it didn't delete)
      //This is important as setting it readonly will create User Access Control (UAC) issues for overwritting 
      //if the read only attribute exists
      if (File.Exists(temp)) { File.SetAttributes(temp, FileAttributes.Temporary ); }

      //Copy original file to temp location. Overwrite if it already exists due to previous deletion failure
      File.Copy(att.FullFileName, temp, true);

      //Set temp file attributes
      File.SetAttributes(temp, FileAttributes.Temporary | FileAttributes.ReadOnly);

      //Start process and monitor
      var p = Process.Start(temp);//Open attachment in default program
      if (p != null) { p.WaitForExit(); }

      //After process ends remove readonly attribute to allow deletion without causing UAC issues
      File.SetAttributes(temp, FileAttributes.Temporary);
      File.Delete(temp);
}
).Start();

I've tested it and so far it seems to be doing the job, but it all feels so messy. I honestly feel like there should be an easier way to handle this that doesn't involve the need to creating new threads. If looked into copying files into memory first, but I can't seem to figure out how to open them in their default application from a MemoryStream.

So my question is.

  1. Is there a better way to achieve opening a readonly, temp copy of a file that doesn’t write to disk first?
  2. If not, what implications could I face from taking the mutlithreaded approach?

Any info is appreciated.

Upvotes: 0

Views: 561

Answers (1)

Martin James
Martin James

Reputation: 24897

Instead of removing the temporary file(s) on shutdown, remove the 'left over' files at startup.

This is often easier to implement than trying to ensure that such cleanup code runs at process termination and handles those 'forced' cases like power fail, 'kill -9', 'End process' etc.

I like to create a 'temp' folder for such files: all of my apps scan and delete any files in such a folder at startup and the code can just be added to any new project without change.

Upvotes: 1

Related Questions