Closed leoner closed 11 years ago
如果是第一次打开浏览器,那么 nodejs 获取的 pid 和用系统命令查看到的 pid 是一致的。 如果已经有打开的浏览器,那么 nodejs 获取的 pid 和系统命令查看的进程的 pid 是不匹配的。 但是我们如果直接杀死第一个浏览器的 pid ,那么后面的浏览器同样会被杀死。 看样子只有了解 win7 下面浏览器加载的方式才行啊。
如果我们新打开第一个浏览器:
iexplore.exe 2256 RDP-Tcp#0 2 18,732 K
iexplore.exe 2236 RDP-Tcp#0 2 21,220 K
其中 2256 为主id. 我们后面在分别打开多个浏览器,不用关心他们的 pid 是多少。然后我们只需要执行
taskkill /pid 2256
执行一次就会杀死最后打开的那个浏览器。
关于精准的关闭某个 ie 窗口,搜索了很多,基本上没有解决方案。目前只要保证系统只维护一个浏览器管理程序,应该是没有问题。下面是一些关于这个原因的参考内容: 其中第一篇基本上最为详细了。
赞,这资料很棒。
记得有接口可以获取到窗口句柄,包括 title,是否可以通过 title 精准匹配到某个具体的 ie 窗口?
On Sat, Apr 13, 2013 at 9:46 PM, hui.kang notifications@github.com wrote:
关于精准的关闭某个 ie 窗口,搜索了很多,基本上没有解决方案。目前只要保证系统只维护一个浏览器管理程序,应该是没有问题。下面是一些关于这个原因的参考内容: 其中第一篇基本上最为详细了。
1. http://answers.microsoft.com/en-us/ie/forum/ie9-windows_vista/after-closing-ie-windows-iexploreexe-processes-are/a3b1536d-1732-4f63-92d3-8fa927946d80 2. http://answers.microsoft.com/en-us/ie/forum/ie8-windows_other/multiple-iexplore-processes/b6f6d249-d30c-4bd7-9b9b-ae647b665beb 3. http://superuser.com/questions/55921/multiple-iexplore-exe-processing-running-in-windows-7 4. http://www.techjunoon.com/kill-processes-from-command-prompt-in-windows-7-and-xp/
— Reply to this email directly or view it on GitHubhttps://github.com/totorojs/browsers-launcher/issues/14#issuecomment-16333352 .
王保平 / 玉伯(射雕) 送人玫瑰手有余香
taskkill /IM iexplore.exe /F
目前通过额外检查系统进程,并通过上面命令,确保浏览器一定能够被关闭。
一些新的补充资料:
下面说的都是在 win7 下面,xp 下面没有此问题。
tasklist /FI "imagename eq iexplore.exe"
tasklist /FI "imagename eq chrome.exe"
只要有浏览器打开,会出现2条己以上记录,其中第一条记录就是主进程的.
tasklist /FI "imagename eq firefox.exe"
比较特殊,不管打开多少个,通过上面的命名,也只会出现一条记录,也就是说子进程的 id 是无法通过这个命令获取的
taskkill /PID 主进程id
这个过程比较有意思,就是如果通过 taskkill 关闭浏览器只能通过主进程 id 来完成。每次执行一次,就会关闭最新打开的那个浏览器。
taskkill /pid subId /F
通过 /F 也是能关闭的,但是:
康辉先试试用 WMIService 能否解决问题: http://blogs.technet.com/b/heyscriptingguy/archive/2004/09/27/how-can-i-terminate-a-process-with-a-specific-pid.aspx
用微软系统自身提供的服务去操控进程,可能可行。
刚才跟沉鱼也简单讨论了一下,browsers-launcher 如果能确保浏览器自身的稳定性(launch、kill、monitor),那么与 totoro-test 的 socket 通信也可以去掉。这样各司其职,简单可靠。
另外一个小建议,浏览器管理服务如果保留的话,端口别用 8080,太容易和 tomcat 冲突了。
刚才电话里的讨论:
这样,将问题从「精准关闭子进程」转换为:
通过 launcher 精准判断某个子进程处于失去响应状态。
如果上面的问题能解决,则不需要建立与 totoro-test 的通信,launcher 自身实现功能自完备。
「精准判断某个子进程处于失去响应状态」目前想到的可尝试思路:
还有一种方式是:
通过与 totoro-test 的交互来知道某个进程是否未响应了。
通过系统命令应该查询不到某个进程的当前状态,参考:
https://groups.google.com/forum/?fromgroups=#!topic/microsoft.public.scripting.vbscript/75jnfApmMjQ
文中提到的一个想法是:
要判断某个进程是否失去了响应,最简单有效的办法是,给该进程发消息,看它是否能继续完成新工作。
对于 browsers-launcher 来说,好像还是得通过 totoro-test 的心跳或定时来判断。
获取浏览器无响应状态的测试 测试方式: 通过执行一个死循环的脚本 最新测试结果:
ie8 会提示 停止脚本执行 的提示。这个时候
直接通过 tasklist 就可以获取这种不响应的状态
虽然浏览器操作起来比较缓慢,但是状态还是可响应的。
所以应该每个浏览器对脚本执行都有不同的策略,所以通过这种外部检测的方式,应该只能成功检查到某些浏览器,也就是这些脚本执行能够导致整个浏览器进行挂死的浏览器,但是大部分其实对这部分是有优化的,比如 ie8 的脚本停止执行的提示。看来最好的方法还是通过和外部(totoro-test)通信的方式来确定浏览器是否可相应是最靠谱的呀. 不过我们可以通过 tasklist 来检查一部分浏览器。
嗯,赞康辉的研究精神。我想能否这样:
直接与 totoro-test 通信,我的担心:
我有一个想法,不知可不可行:
就是本地的 launcher 通过本地的 socket 通信管理本地的 browsers
这样:
康辉看看上面的方式是否可行?
恩,我今天也是准备按照这个思路来处理呀!现在就是准备测试以下浏览器假死状态下,socket的通信的状况。如果这种方式可行的话,虽然就是 capture 的 js 有一点耦合,但是这个应该可以接受。后续测试没有问题的话,就会按照这个思路来实现呀!
好,期待进一步进展。
这个不在继续深入了,后续转向 #26 来处理相关问题。
有种柳暗花明的感觉啊,问题一下子简单了
现象: 如过当前已经存在运行着的 ie 浏览器,那么当通过 spawn 再次打开浏览器的时候,在 xp ,浏览器的进程句柄会被保持着,而在 win7 下面,成功打开新的浏览器后直接会触发 process 的 close 事件,而且返回码是0,但是检查 process.killed 属性是 false.说明此进程还是没有退出的。而且此进程通过
process.kill()
也无法关闭. 解决: