Как открыть файл HTML в браузере по умолчанию и удалить его после просмотра пользователем?

Я пытаюсь открыть временный файл 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 возвращает null, если процесс не запущен, но используется работающий (открывается новая вкладка в Google Chrome). Поэтому я не могу дождаться завершения этого процесса.

Итак, общий вопрос: как выполнить задание? Как показать пользователю временный HTML-файл и удалить его после просмотра?


person Artem Kachanovskyi    schedule 16.06.2015    source источник
comment
Подождать пару секунд и удалить файл? (Браузер не должен блокировать его), хотя это предотвратит обновление   -  person Alex K.    schedule 16.06.2015
comment
Здесь творится Джеймс Бонд....   -  person Botonomous    schedule 16.06.2015
comment
Это предотвратит обновление. И пользователь может обнаружить, что файл отсутствует на диске, что странно.   -  person Artem Kachanovskyi    schedule 16.06.2015
comment
Вы видели programmingforums.org/post172293.html?   -  person artm    schedule 16.06.2015
comment
Если вы не можете использовать предложение Алекса К., то лучше всего будет удалить файл при запуске вашей программы, если он все еще там. Вы не можете разумно предположить, что пользователь закроет браузер, когда прочитает документ.   -  person Andrew Morton    schedule 16.06.2015
comment
@artm, я раньше не видел этого обсуждения, но похоже, что там все равно нет ответа.   -  person Artem Kachanovskyi    schedule 16.06.2015
comment
@AndrewMorton, но есть ли способ получить процесс, который фактически открыл файл, и дождаться его выхода?   -  person Artem Kachanovskyi    schedule 16.06.2015


Ответы (3)


Если вы используете ProcessStartInfo и устанавливаете UseShellExecute затем вы можете запустить браузер пользователя по умолчанию, "запустив" HTML напрямую, как вы пытаетесь сделать сейчас. Я не пробовал, но он должен вернуть вам Process, чтобы определить, когда пользователь закрыл браузер.

Я бы все равно подготовился к множеству крайних случаев, которые вы не можете контролировать. Например, если они оставляют браузер открытым, но закрывают приложение, которое наблюдает за браузером. В этот момент вы позволяете браузеру оставаться в живых? Вы убиваете это? Когда вы удаляете файл HTML? Возможно, лучше использовать Веб-браузер. Тогда вам даже не придется беспокоиться о других процессах или совместимости браузера. Вы даже можете передавать содержимое HTML в элемент управления, и нет файла, который можно было бы удалить позже.

person Corey Ogburn    schedule 16.06.2015
comment
Использование свойства ShellExecute не помогает: когда я устанавливаю его в false, файл вообще не открывается. Что касается WebBrowser, мне это решение не очень нравится: оно зависит от IE и, насколько я знаю, в WebBrowser не так просто использовать все возможности браузера: панели инструментов, вкладки и так далее. Но вы правы, пользователь может закрыть программу и оставить браузер. Тогда делать по сути нечего. Еще одним возможным решением было бы удалить файл при выходе из приложения... - person Artem Kachanovskyi; 16.06.2015
comment
Оно не должно быть ложным. Вам нужно использовать оболочку, поэтому это должно быть правдой. Но похоже, что вы вернетесь в лодку, в которой находитесь сейчас (Process.Start возвращает null) - person Corey Ogburn; 16.06.2015
comment
Да, это так. Возвращенный Process равен нулю. - person Artem Kachanovskyi; 16.06.2015

Вы можете принудительно создать новый экземпляр браузера, сначала выяснив браузер по умолчанию и запустив его вручную:

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)
{
}
person Dave Bish    schedule 16.06.2015
comment
Это возможно, но немного сложно и небезопасно - person Artem Kachanovskyi; 16.06.2015
comment
Я думаю, что вся эта идея сложна и небезопасна! - person Dave Bish; 16.06.2015

Вы также можете прочитать содержимое html в поток памяти или в строковую переменную с помощью WebClient, и после закрытия потока или веб-клиента файл будет выпущен, готовый к удалению, поскольку он вам больше не нужен.

У вас есть html-контент в памяти, просто отправьте его в браузер.

Вот пример, если вам нужно:

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

Надеюсь, поможет.

person Ricardo Pontual    schedule 16.06.2015