【问题标题】:How to open HTML file with default browser and delete it after user viewed it?如何使用默认浏览器打开 HTML 文件并在用户查看后将其删除?
【发布时间】:2015-06-16 13:47:09
【问题描述】:

我尝试使用默认浏览器打开临时 HTML 文件,然后删除该文件:

        var tempFileName = Path.ChangeExtension(Path.GetTempFileName(), "html");
        // I save document to temp file here...

        Process process = null;
        try
        {
            process = Process.Start(tempFileName);
        }
        catch (Win32Exception)
        {
        }
        catch (ObjectDisposedException)
        {
        }
        catch (FileNotFoundException)
        {   
        }

        var worker = new BackgroundWorker();
        worker.DoWork += (s, we) => {
            if (process != null)
            {
                process.WaitForExit();
                try
                {
                    File.Delete(tempFileName);
                }
                catch (IOException)
                {
                }
            }
        };
        worker.RunWorkerAsync();

不幸的是,Process.Start 如果未启动进程但使用正在运行的进程(在 Google Chrome 中打开新选项卡),则返回 null。所以我等不及该进程退出了。

所以,一个普遍的问题是:如何完成任务?如何向用户显示临时 HTML 文件并在查看后将其删除?

【问题讨论】:

  • 等待几秒钟然后删除文件? (浏览器不应该锁定它)虽然这会阻止刷新
  • 詹姆斯邦德的事情发生在这里......
  • 这将阻止刷新。用户可能会发现磁盘上丢失的文件很奇怪。
  • 如果您不能使用 Alex K. 的建议,那么下一个最好的方法是在您的程序启动时删除该文件(如果它仍然存在)。您不能合理地假设用户在阅读完文档后会关闭浏览器。

标签: c# html .net temporary-files default-browser


【解决方案1】:

如果您使用ProcessStartInfo 并设置UseShellExecute,那么您可以通过直接“运行”HTML 来启动用户的默认浏览器,就像您现在尝试做的那样。我还没有尝试过,但它应该会给你一个Process 来确定用户何时关闭了浏览器。

我仍然会为一堆你无法控制的边缘情况做准备。例如,如果他们让浏览器保持打开状态,但关闭正在观看浏览器的应用程序。那时你让浏览器保持活力吗?你杀了它吗?什么时候删除 HTML 文件?使用Web Browser 控件可能会更好。然后您甚至不必担心其他进程或浏览器兼容性。您甚至可以将 HTML 内容流式传输到控件,以后无需删除任何文件。

【讨论】:

  • 使用ShellExecute 属性没有帮助:当我将它设置为false 时,文件根本没有打开。至于WebBrowser,我不太喜欢这个解决方案:它依赖于IE,据我所知WebBrowser 使用浏览器带来的所有功能并不容易:工具栏、选项卡等。但你是对的,用户可能会关闭程序并保留浏览器。那么其实也没什么可做的。另一种可能的解决方案是在应用程序退出时删除文件...
  • 不应该是假的。您确实需要使用外壳,因此它必须是真实的。但听起来你会回到你现在所在的船上(Process.Start 返回 null)
  • 是的,就是这样。返回的Process 为空。
【解决方案2】:

你可以强制一个新的浏览器实例,首先找出默认浏览器,然后手动执行它:

public Process launchBrowser(string url)
{
    string browserName = "iexplore.exe";
    using (RegistryKey userChoiceKey = Registry.CurrentUser.OpenSubKey(@"Software\Microsoft\Windows\Shell\Associations\UrlAssociations\http\UserChoice"))
    {
        if (userChoiceKey != null)
        {
            object progIdValue = userChoiceKey.GetValue("Progid");
            if (progIdValue != null)
            {
                if(progIdValue.ToString().ToLower().Contains("chrome"))
                    browserName = "chrome.exe";
                else if(progIdValue.ToString().ToLower().Contains("firefox"))
                    browserName = "firefox.exe";
                else if (progIdValue.ToString().ToLower().Contains("safari"))
                    browserName = "safari.exe";
                else if (progIdValue.ToString().ToLower().Contains("opera"))
                    browserName = "opera.exe";
            }
        }
    }

    return Process.Start(new ProcessStartInfo(browserName, url));
}

然后你就可以得到进程的句柄了:

var process = launchBrowser("www.google.com");

process.WaitForExit();

try
{
    //Do whatever
}
catch (IOException)
{
}

【讨论】:

  • 这可行,但有点复杂和不安全
  • 我认为整个想法既复杂又不安全!
【解决方案3】:

您也可以使用WebClient将html内容读入Memory Stream或字符串变量,关闭Stream或WebClient后,文件将被释放,准备删除,因为您不再需要它。

你在内存中有 html 内容,只需将其发送到浏览器。

如果你需要,这里有一些例子:

https://social.msdn.microsoft.com/Forums/vstudio/en-US/060ea8e0-cc63-44a3-b0dc-b531c29b8a0f/read-html-content-using-cnet?forum=csharpgeneral

希望对你有帮助。

【讨论】:

    猜你喜欢
    • 2012-04-17
    • 1970-01-01
    • 1970-01-01
    • 2021-10-09
    • 2018-10-19
    • 1970-01-01
    • 2014-12-21
    • 2014-12-06
    • 1970-01-01
    相关资源
    最近更新 更多