I'm writing a windows forms application i C#, where I'll need to open a document/file (.doc, .pdf, .xlsx, .tiff etc.) to the user in an associated program installed on the client pc.
The file should be deleted as soon the user closes the displaying program.
I've tried several options for creating and opening the file, but haven't found the golden egg yet.
public static void databaseFileRead(string file_name, byte[] file)
{
path = file_name;
int file_size_int = file.Length;
FileStream create = new FileStream(@path, FileMode.Create, FileAccess.ReadWrite, FileShare.Read, file_size_int, FileOptions.DeleteOnClose);
create.Write(file, 0, file_size_int);
FileStream open = File.Open(@path, FileMode.Open, FileAccess.ReadWrite, FileShare.Read);
}
In the above method I'm getting an IOException stating that "The process cannot access the file 'xxx' because it is being used by another process" on last line (FileStream open = ...
).
public static void databaseFileRead(string file_name, byte[] file)
{
path = file_name;
int file_size_int = file.Length;
FileStream create = File.OpenWrite(@path);
var attributes = File.GetAttributes(@path);
File.SetAttributes(@path, attributes | FileAttributes.ReadOnly|FileAttributes.Temporary);
create.Close();
Process p = Process.Start(@path);
p.WaitForExit();
File.Delete(@path);
}
And in this method I'm also getting an IOException stating that "The process cannot access the file 'xxx' because it is being used by another process" on last line (File.Delete(@path);
) meaning that the file is still in use, which is correctly. It seems that p.WaitForExit();
is not waiting for all programs e.g. OpenOffice...
Is it possible to open/display a file created with FileOptions.DeleteOnClose
in an external program?
If so, how?
I do like the idea, that Windows is deleting the file as soon that the file isn't used anymore.
It is important that the files disappear from the users hard drive automatically, the best option, would be to read and open the file from a stream or equal. But as far that I have read, this is not possible...
SOLVED:
However I'm not sure if it's a prober way to catch the exception and call the closeIfReady
method again until the file is released...
public static void databaseFileRead(string file_name, byte[] file)
{
var path = file_name;
int file_size_int = file.Length;
if (File.Exists(path))
{
File.Delete(path);
}
FileStream create = File.OpenWrite(path);
create.Write(file, 0, file_size_int);
var attributes = File.GetAttributes(path);
File.SetAttributes(path, attributes | FileAttributes.Temporary);
create.Close();
Process p = Process.Start(path);
while (!p.HasExited)
{
Thread.Sleep(500);
}
closeIfReady(path);
}
static void closeIfReady(string path)
{
try
{ File.Delete(@path); }
catch
{
Thread.Sleep(1000);
closeIfReady(path);
}
}