如何从PowerShell启动时正确关闭Internet Explorer? [英] How to properly close Internet Explorer when launched from PowerShell?

查看:1665
本文介绍了如何从PowerShell启动时正确关闭Internet Explorer?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有一组最近提出的问题,关于通过PowerShell做一些与Internet Explorer的东西。所有这些都包含通过 $ ie = new-object -comobject InternetExplorer.Application 作为对象从PowerShell启动IE的代码。问题是,关闭 IE的正确方式,包括调用 $ ie.quit()不工作 - 首先,如果该IE发生了一个以上的单个打开的选项卡,IE不退出作为一个整体,只有对应于COM对象的选项卡关闭,其次,如果它只有一个选项卡,窗口被关闭,但进程保留。

There was a set of recently asked questions about doing something with Internet Explorer via PowerShell. All of them contain codes to launch IE from PowerShell as an object, via $ie=new-object -comobject InternetExplorer.Application. The problem is, the proper way of closing IE that consists of calling $ie.quit() does not work - first, if that IE would have happened to have more than a single open tab, IE doesn't quit as a whole and only the tab that corresponds to the COM object is closed, and second, should it have only one tab, the window gets closed but the processes remain.

PS > get-process iexplore

Handles  NPM(K)    PM(K)      WS(K) VM(M)   CPU(s)     Id ProcessName
-------  ------    -----      ----- -----   ------     -- -----------
    352      31     7724      24968   142     0,58   3236 iexplore
    228      24    22800      15384   156     0,19   3432 iexplore

我试图研究方法关于如何关闭通过 New-Object -ComObject 启动的进程,并发现这个:如何摆脱COMObject 。该COMObject的例子是 Excel.Application ,这的确如预期 - 调用 quit()使窗口关闭,并执行 [System.Runtime.Interopservices.Marshal] :: ReleaseComObject($ ex)如果 $ ex COMObject停止Excel进程。但是这不是Internet Explorer的情况。

I have tried to research the methods on how to close a process started via New-Object -ComObject, and have found this: How to get rid of a COMObject. The example of that COMObject is Excel.Application, which indeed behaves as intended - calling quit() makes window close, and executing [System.Runtime.Interopservices.Marshal]::ReleaseComObject($ex) if $ex is a created COMObject stops the Excel process. But this is not the case with Internet Explorer.

我还发现了这个问题:如何获取一个正在运行的IE的现有COM对象,它提供了代码通过打开的窗口列表连接到IE,并工作到一定程度的IE从其他地方启动,但如果COM对象是通过PowerShell创建的,这个脚本不能完全停止IE的进程,如果这样修改:

I have also found this question: How to get existing COM Object of a running IE which provides code to connect to IE via list of open windows, and works to an extent of IE launched from elsewhere, but if the COM object is created via PowerShell, this script is not able to completely stop IE's processes, if modified as such:

$shellapp = New-Object -ComObject "Shell.Application"
$ShellWindows = $shellapp.Windows()
for ($i = 0; $i -lt $ShellWindows.Count; $i++)
{
 if ($ShellWindows.Item($i).FullName -like "*iexplore.exe")
  {
  $ie = $ShellWindows.Item($i)
  $ie.quit()
  [System.Runtime.Interopservices.Marshal]::ReleaseComObject($ie)
  }
}


b $ b

如果IE在PowerShell外部启动,进程将停止,但是在PowerShell中启动IE的情况下,会有两个进程保留,并且此代码报告没有找到任何IE窗口来访问COM对象,因此IE

In case of IE launched outside of PowerShell, the processes are stopped, but in case of IE launched within PowerShell, two processes remain, and this code reports to have found no IE windows to reach COM objects, therefore IE processes are (yet) unable to be stopped.

那么,如何到达明显孤立的无窗口IE进程,并优雅停止它们呢?我知道 Get-Process iexplore | Stop-Process ,但这将停止任何和所有的IE,而不仅仅是那些由脚本启动的,以及如果脚本以管理员或 SYSTEM

So, how to reach the apparently orphaned windowless IE processes and gracefully stop them? I am aware of Get-Process iexplore | Stop-Process, but this will stop any and all IEs, not just those launched by the script, and if the script is run as administrator or SYSTEM on a, say, remote desktop server, everyone's IEs will be stopped.

环境:
操作系统Windows 7 x64,PowerShell 4(安装在PS版本2之上) ),IE11版本11.0.9600.17691(自动更新)。 IE在启动时设置为打开主页,因此至少有一个标签页始终打开。

Environment: OS Windows 7 x64, PowerShell 4 (installed above PS version 2), IE11 version 11.0.9600.17691 (automatically updated). IE set to "Open home page" upon starting, so at least one tab is always open.

推荐答案

c $ c> Quit()方法通常足以正常终止Internet Explorer进程,而不管它们是通过运行 iexplore.exe 通过在PowerShell中实例化COM对象。

Simply calling the Quit() method should normally suffice for gracefully terminating Internet Explorer processes, regardless of whether they were created by running iexplore.exe or by instantiating a COM object in PowerShell.

演示:

PS C:\> $env:PROCESSOR_ARCHITECTURE
AMD64
PS C:\> (Get-WmiObject -Class Win32_OperatingSystem).Caption
Microsoft Windows 8.1 Enterprise
PS C:\> Get-Process | ? { $_.ProcessName -eq 'iexplore' }
PS C:\> $ie = New-Object -COM 'InternetExplorer.Application'
PS C:\> Get-Process | ? { $_.ProcessName -eq 'iexplore' }

Handles  NPM(K)    PM(K)      WS(K) VM(M)   CPU(s)     Id ProcessName
-------  ------    -----      ----- -----   ------     -- -----------
    352      20     4244      14164   176     0.05   3460 iexplore
    407      32     6428      23316   182     0.23   5356 iexplore

PS C:\> $ie.Quit()
PS C:\> Get-Process | ? { $_.ProcessName -eq 'iexplore' }
PS C:\> _

如果你有孤立的Internet Explorer进程,你没有一个句柄,你可以循环通过他们,像这样:

If you have orphaned Internet Explorer processes to which you don't have a handle you can cycle through them like this:

(New-Object -COM "Shell.Application").Windows() |
  ? { $_.Name -like "*Internet Explorer*" } |
  % { $_.Quit() }

可以在调用 Quit()后释放COM对象,然后等待垃圾回收器清除:

To be totally on the safe side you can release the COM object after calling Quit() and then wait for the garbage collector to clean up:

(New-Object -COM "Shell.Application").Windows() |
  ? { $_.Name -like "*Internet Explorer*" } |
  % {
    $_.Quit()
    [Runtime.Interopservices.Marshal]::ReleaseComObject($_)
  }

[GC]::Collect()
[GC]::WaitForPendingFinalizers()

这篇关于如何从PowerShell启动时正确关闭Internet Explorer?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆