C# 暂时保存、打开,然后在关闭时删除

C# 暂时保存、打开,然后在关闭时删除,c#,file,process,C#,File,Process,我需要临时保存并打开下载的文件。产品所有者声明的需求是不必通过文件保存对话框来检索这些文件,也不必让文件无限期地存放在他们的硬盘上 为此,我在下载这些文件时实现了“仅查看”选项。使用时,文件将以默认文件名保存到用户的Internet临时文件目录中,然后使用默认程序使用Process.Start(fileName)打开。这种行为模仿了我的桌面应用程序所基于的web UI 问题出在这里。用户希望我更进一步,当用户关闭打开查看文件的程序时,立即删除该文件。“没问题”,我想,然后写了以下代码:

我需要临时保存并打开下载的文件。产品所有者声明的需求是不必通过文件保存对话框来检索这些文件,也不必让文件无限期地存放在他们的硬盘上

为此,我在下载这些文件时实现了“仅查看”选项。使用时,文件将以默认文件名保存到用户的Internet临时文件目录中,然后使用默认程序使用
Process.Start(fileName)
打开。这种行为模仿了我的桌面应用程序所基于的web UI

问题出在这里。用户希望我更进一步,当用户关闭打开查看文件的程序时,立即删除该文件。“没问题”,我想,然后写了以下代码:

    protected static readonly ConcurrentDictionary<int, Process> OpenFileViewers 
        = new ConcurrentDictionary<int, Process>();

    protected void LaunchFileAndWatch(string fileName, Action<string> closeFileCallback)
    {
        try
        {
            var process = Process.Start(fileName);

            OpenFileViewers.TryAdd(process.Id, process);

            process.WaitForExit();

            OpenFileViewers.TryRemove(process.Id, out process);

            closeFileCallback(fileName);

        }
        catch (Exception ex)
        {
            HandleExceptionInUIThread(ex);
        }
    }

    protected virtual void HandleExceptionInUIThread(Exception ex)
    {
        if (InvokeRequired)
        {
            this.Invoke(new Action<Exception>(HandleExceptionInUIThread), ex);
            return;
        }

        //TODO: Whatever we want to do with the exception; for now, throw it out to ThreadException handler
        throw ex;
    }

    protected void DeleteFile(string fileName)
    {
        try
        {
        File.Delete(fileName);
        }
        catch (Exception ex)
        {
            HandleExceptionInUIThread(ex);
        }
    }

...

((Action<string, Action<string>>)LaunchFileAndWatch).BeginInvoke(downloadedFileName, DeleteFile, null, null);
受保护的静态只读ConcurrentDictionary OpenFileViewer
=新的ConcurrentDictionary();
受保护的void LaunchFileAndWatch(字符串文件名,操作closeFileCallback)
{
尝试
{
var process=process.Start(文件名);
OpenFileViewers.TryAdd(process.Id,process);
process.WaitForExit();
OpenFileViewers.TryRemove(process.Id,out进程);
closeFileCallback(文件名);
}
捕获(例外情况除外)
{
HandleExceptionUIThread(ex);
}
}
受保护的虚拟void handleExceptionUIThread(异常ex)
{
如果(需要调用)
{
调用(新操作(HandleExceptionUIThread),例如;
返回;
}
//TODO:无论我们想对异常执行什么操作;现在,将其抛出到ThreadException处理程序
掷骰子;
}
受保护的void DeleteFile(字符串文件名)
{
尝试
{
删除(文件名);
}
捕获(例外情况除外)
{
HandleExceptionUIThread(ex);
}
}
...
((操作)LaunchFileAndWatch).BeginInvoke(下载文件名,删除文件,null,null);
ConcurrentDictionary允许我在应用程序关闭时关闭任何打开的查看器程序(如果用户愿意),这样也可以删除文件

问题是,当调用
Process.Start()
实际上没有启动新进程时,此代码将失败。我不知道会发生这种情况,但显然shell将重用现有进程,当这种情况发生时,您无法从任何版本的
进程中获取进程信息。启动
,无论是静态的还是实例的

在这种情况下,文件不会被删除,用户也不会满意


是否有一种方法可以使用
进程打开文件。启动
,强制Windows让我控制进程,而不必放弃使用Windows的默认程序数据库?

您是否尝试过单步执行代码。。另外,他们希望您立即删除的文件类型是什么?您是否可以创建一个类来读取数据并将其存储在内存中,然后在读取所有文本后立即删除该文件。。而且,这将消除使用Process.Start()的需要,除非我不完全理解您的问题。请检查并。。。它可能适用于某些情况。。。另外,一般来说,Windows没有“相应的应用程序已完成读取此文件”的概念,因此当出现问题时,总会出现一些情况-无法删除/过早删除…@MethodMan,我认为您不理解。所讨论的文件或多或少是日常数据文件,如JPGs、PDF、Excel/Word文件等。不完全是纯文本,但不是本系统的专有文件,因此我希望使用Windows选择的任何程序打开该文件。因此,自然的选择是过程。开始。但是,有些默认程序不会为每个文件创建新实例,还有一些根本不会创建新实例(它们是操作系统外壳的一部分),因此不可能总是让流程实例进行监视。@AlexeiLevenkov-谢谢,我会看看是否可以做到这一点。P/Invoke并不理想,但对情况了解很少;理想情况下,PO会很高兴将文件放入Internet缓存并及时处理。