Как закрыть Internet Explorer, если он был запущен с помощью Process.Start?

У меня есть приложение WPF, которое запускает Internet Explorer (версия 9, на Win7 X64) с использованием метода Process.Start.

Я сохраняю ProcessID, чтобы закрыть его при закрытии приложения. Однако, когда приложение закрывается, Internet Explorer по-прежнему виден в диспетчере задач.

Вот код, который я использую:

public class MyClass : IDisposable
{
    Process _process;


    public void Go()
    {

        ProcessStartInfo psi = new ProcessStartInfo { 
            FileName = "iexplore.exe", 
            Arguments = "-noframemerging -private \"http://whathaveyoutried.com\"" 
        };
        _process = Process.Start(psi);
        _process.WaitForInputIdle();
    }

    private void Close(object sender, RoutedEventArgs e)
    {
        if (_process != null)
        {
            _process.Refresh();
            _process.Close();
        }
    }

    public void Dispose()
    {
        if (_process != null)
        {
            _process.Refresh();
            _process.Close();
        }
    }
}

}

Я дважды проверил, вызов _process.Close() действительно выполнен.

Что может вызвать такое поведение?

PS: я подозреваю, что это связано с внутренним Internet Explorer. Запуск exe не обязательно создает новый процесс, но может использовать некоторые IPC для управления другими экземплярами. Я использую аргумент командной строки -noframemerging, но он не решает проблему.

[Изменить] Это продолжение другого вопроса, который я задал несколько дней назад. На самом деле, я вызываю функцию SetParent, чтобы внедрить созданный IE в свое приложение. Я не могу использовать элемент управления WebBrowser, поскольку он не поддерживает изоляцию, которую я ищу. Так что нормально закрывать IE, когда мое приложение закрывается.


person Steve B    schedule 05.07.2012    source источник
comment
Если вы запускаете видимое приложение, оно принадлежит пользователю, а не вашему приложению (например, они могут открыть там новые вкладки). Если вам нужен ограниченный браузер, используйте какой-либо элемент управления браузером в окне, принадлежащем вашему приложению.   -  person Damien_The_Unbeliever    schedule 05.07.2012
comment
За этим требованием стоит небольшая предыстория. По сути, я не могу использовать элемент управления WebBrowser, поэтому я запускаю новый IE и присоединяю его окна к моему приложению с помощью SetParent. Это работает, немного некрасиво, но работает. Единственным недостатком является то, что я не знаю, как на самом деле отслеживать реальный процесс, и это приводит к фантомным процессам в памяти. Но вы правы. В «стандартном» сценарии это было бы плохой практикой :)   -  person Steve B    schedule 05.07.2012
comment
Как я уже сказал, еще одним недостатком является то, что пользователь начинает относиться к этому экземпляру IE как к любому другому (он может быть не в состоянии отличить их друг от друга) и открывает новые вкладки, указывая на страницы, которые не имеют к вам никакого отношения. пользователь не ожидает, что выход из вашего приложения уничтожит одно из его окон IE.   -  person Damien_The_Unbeliever    schedule 05.07.2012


Ответы (3)


Каждая вкладка Internet Explorer — это процесс. Если вы открываете IE с несколькими вкладками или пользователь открывает другие вкладки, этого будет недостаточно, чтобы убить процесс.

Но

_process.Close();

Освобождает все ресурсы, принадлежащие _process. Вместо него можно использовать метод _process.Kill().

person Mehmet Ali Sert    schedule 05.07.2012
comment
Это фактически убивает экземпляр Internet Explorer. Мне немного не нравится этот метод, потому что я не уверен, что уничтожение процесса вместо того, чтобы приказать ему завершить работу должным образом, не будет иметь побочных эффектов. - person Steve B; 05.07.2012
comment
_Process.Close() в конечном итоге вызывает _Process.Kill(), поэтому я не вижу разницы. Вы даже не пробовали, чтобы увидеть, может ли это сработать, я имею в виду, что вы уже используете хак, чтобы делать то, что вы хотите. - person Security Hound; 05.07.2012

Для повышения безопасности и стабильности IE8 использует архитектуру слабосвязанного Internet Explorer (LCIE) и запускает фрейм и вкладки браузера в отдельных процессах. LCIE предотвращает сбои и зависания всего браузера и обеспечивает более высокую производительность и масштабируемость. Я прочитал это в Википедии.

Вы можете отключить LCIE, но я не уверен, зачем вам это нужно. Я бы подумал об использовании решения, упомянутого выше @Damien_The_Unbeliever.

person Black Frog    schedule 05.07.2012
comment
Я не буду отключать LCIE или что-то еще, что может изменить конфигурацию пользователя. Как я сказал @damien_the_unbeliever, я не могу использовать элемент управления веб-браузером для более сложной проблемы. К вашему сведению, я использую -noframemerging, чтобы убедиться, что IE запускается в новом процессе (фактически в новом сеансе). Может быть, есть способ попросить этот конкретный экземпляр IE закрыть все его вкладки? - person Steve B; 05.07.2012
comment
Теперь вы знаете, почему идентификатор процесса не тот, вы должны задать новый вопрос. Как получить/найти идентификатор процесса определенной вкладки в IE9? - person Black Frog; 05.07.2012

У меня есть приложение IE в моем приложении win32, и я использую Win32Api - SendMessage with WM_CLOSE = 0x0010

SendMessage(handle,0x0010,IntPtr.Zero, IntPtr.Zero)}

Это закрывает IE, однако вам нужно иметь конкретный дескриптор браузера (класс IEFrame).

Есть один недостаток: если у вас более одной вкладки, IE открывает диалоговое окно подтверждения закрытия, которое предотвращает процесс закрытия.

Один из способов обойти открытие диалогового окна — установить для него флажок (всегда закрывать), но для меня это не вариант.

person Tsur Shapira    schedule 03.03.2016