我正在编写一个Windows表单应用程序i C#,我需要在安装在其上的相关程序中向用户打开文档/文件(.doc,.pdf,.xlsx,.tiff等)。客户端电脑。
用户关闭显示程序后,应立即删除该文件。
我已经尝试了几种创建和打开文件的选项,但还没有找到金蛋。
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);
}
在上面的方法中,我得到一个IOException,声明“进程无法访问文件'xxx',因为它正被另一个进程使用”在最后一行(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);
}
在这个方法中,我还得到一个IOException,声明“进程无法访问文件'xxx',因为它正被另一个进程使用”在最后一行({{1} })意味着该文件仍在使用中,这是正确的。 File.Delete(@path);
似乎没有等待所有程序,例如的OpenOffice ...
是否可以在外部程序中打开/显示使用p.WaitForExit();
创建的文件?
如果是这样,怎么样?
我确实喜欢这样的想法,即Windows不再使用该文件就会删除该文件。
重要的是文件自动从用户硬盘中消失,最好的选择是从流中读取和打开文件或相等。但就我所读到的情况而言,这是不可能的......
解决:
但是我不确定是否可以采用这种方法来捕获异常并再次调用FileOptions.DeleteOnClose
方法,直到文件被释放...
closeIfReady
答案 0 :(得分:3)
好的,在评论之后,这是一个有效的第二种方法:
void Method2(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);
var attributes = File.GetAttributes(path);
File.SetAttributes(path, attributes | FileAttributes.Temporary);
create.Close();
Process p = Process.Start(path);
while (!p.HasExited)
{
Thread.Sleep(100);
}
File.Delete(path);
}
你一开始并不严格需要if.File.Exists / File.Delete,我只需要它在我的调试中 - 但是,如果有人在之前退出应用程序,可能是个好主意。文件被删除它将尝试再次创建它。
此方法中的问题是:
File.SetAttributes(@path, attributes | FileAttributes.ReadOnly|FileAttributes.Temporary);
由于文件是以只读方式创建的,因此无法使用File.Delete将其删除。在Windows资源管理器中,如果您有管理员,它不关心这个,这就是为什么你可以从那里删除它,但C#确实关心文件属性。我将该行更改为File.SetAttributes(@path, attributes | FileAttributes.Temporary);
,现在可以正常工作。
This question是我用于p.WaitForExit问题的引用。我建议在你的应用程序的另一个线程上启动它,否则你的应用程序将挂起,而它检查线程已退出(在Windows中变为白色/灰色并告诉你它没有响应)。如果您正在使用wpf,或者重新绘制GUI以便仍然可以使用它,那么您可以执行诸如使视觉效果无效之类的操作,但这些操作非常糟糕并且可能占用大量CPU。
答案 1 :(得分:0)
有几件事。
首先,如果这是在winforms应用程序的主UI线程中运行,那么使用任一解决方案都会使您的应用程序无响应。
其次,两种解决方案都依赖于从多个不同应用程序的优雅退出。这是有风险的。
如果外部进程无法正确清理文件句柄,那么您的解决方案将导致无限递归。我也会感到不舒服,取决于Process.HasExit,因为我已经看到很多关于这个属性可靠性的线索。
我建议使用相对于您的应用程序的临时目录,并在应用程序出口和启动时清理该目录(以防您自己的应用程序无法正常退出)。