在 VB 中调用外部程序用 SHELL  获取 pid 的问题:Private Sub Command1_Click()
    pid = Shell("C:\Program Files\Internet Explorer\iexplore", vbNormalFocus)
End Sub
第一次打开不管是在 WIN7 还是 XP 中都没问题。但是当再次点击 command1 按钮时,打开 windows任务管理器,发现了一个奇怪的问题:前提浏览器均为 IE8
1、在 win7 中,windows任务管理器中新出现的 ie 进程 pid 与返回的 pid 不符;
2、在win XP 中,windows 任务管理器中根本就不会再增加 ie 进程;所以导致 我下一步无法针对 pid 进行 IE 的关闭,求解决思路(注意,我要打开多个 IE 浏览器窗口)。

解决方案 »

  1.   

    再仔细观察了一下,准确的说不管是在 XP 还是 WIN7 中第一次运行的时候在任务管理器中会产生一个新的 IE 进程, shell 也能正常捕获的到
    但是第二次、第三次运行 shell 的时候任务管理器中会临时出现新的 IE 进程,但是马上又消失了。
    既然 进程都不在了,所以也就无法完成对指定窗口的关闭了。==================================================
    思考:直接点击桌面上的 IE 图标 任务管理器中就会创建 新的 IE 进程,为啥在 VB 中通过 shell 就不能呢?
      

  2.   

    被我试出来了,加 /new 即可解决。即
    pid = Shell("C:\Program Files\Internet Explorer\iexplore.exe /new", vbNormalFocus)但问题又来了,这样是正确获取到了pid(后续程序也能关闭了),但打开的同时ie会直接访问  http://new 。这儿应该如何写 啊?
      

  3.   

    悲催的是参数只能 /new 这样写,换成 -new 都不行。各位大侠,如何解决?
      

  4.   

    我这儿测试,加 -new 是可以的。
    IE的“特定命令行参数”是用-符号标识的,估计不是用“-”开头的参数,它就认为是一个URL。
    另外,如果仅仅是“试效果”的话,可以试试加参数: -nohome (启动IE、打开“空白”窗口)但是我发现一个问题:
    如果启动IE新进程、并指定它打开网址URL1;
    但进入URL1时,它会“自动跳转”到URL2(发生了一次或多次“重定向”),最终新进程的PID跟“启动进程”时的PID是不一样的。
      

  5.   

    Shell “cmd /d taskkill /F /IM iexplore.exe",vbHide
      

  6.   


    我想问你一下你
    一、你上面就是一个举例 用shell打开一个外部程序 ,还是就是要打开ie
    二、如果你通过shell打开ie,不知你想做什么操作,还是就是为了关闭?因为程序不知你什么时候操作完成。
    三、如果你想打开以后 ,得到pid,可以试试 我给你的函数
    Const SYNCHRONIZE = &H100000Const INFINITE = &HFFFFFFFFPrivate Declare Function OpenProcess Lib "kernel32" (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwProcessId As Long) As LongPrivate Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As LongPrivate Declare Function WaitForSingleObject Lib "kernel32" (ByVal hHandle As Long, ByVal dwMilliseconds As Long) As LongDeclare Function WinExec Lib "kernel32" (ByVal lpCmdLine As String, ByVal nCmdShow As Long) As LongPublic Function ShellWait(SheStr As String) As Long    Dim pId As Long, pHnd As Long              
        
       pId = Shell(SheStr, vbHide)        pHnd = OpenProcess(SYNCHRONIZE, 0, pId)       If pHnd <> 0 Then        Call WaitForSingleObject(pHnd, INFINITE)        Call CloseHandle(pHnd)    End If    ShellWait = pId
        
    End Function调用方式 :pid=shellwait("C:\Program Files\Internet Explorer\iexplore")四、如果就是要使用ie,那建议你使用webbrowser控件,很方便,随便控制
      

  7.   

    再次灰常谢谢各位的热心。我的问题解决了,也给大家分享一下。
    我的目标是:利用设置代理IP 来刷流量,主要是IP量哈(用途,有无意义我们就不追究了哈)1、第一步通过api 获取到代理IP;
    2、设置IE代理服务,访问指定网页。如果利用 webbrowser 控件,非常顺手。最开始我也是这么做的,为了提高效率,我还用了多个窗口来放  webbrowser 控件,每个FORM窗体设置各自的代理IP。但是这种方式对 cnzz,51.la 等第三方统计无效(奇怪的是webbrowser 控件访问我的 php 程序 $_SERVER['REMOTE_ADDR']  显示的IP是代理IP,思索了很久没找到问题所以放弃了)现在的方法是通过代码修改注册表直接设置 IE 浏览器的代理,第三方统计也认可了。
    另外,海鸥软件 提到的没法检测是否完成,何时完成确实是个问题。不过我不管那么多,也不用一直等待,我是定时 kill 掉打开时候的 pid 即可。
      

  8.   

    补充:如果直接打开 IE  就会有我主题上描述的问题(经过我测试,只有 IE 有pid这个问题)。
    解决方法(可能有点笨):另外做一个 exe 文件,这个 exe 里只放一个 webbrowser 控件,再用主程序去 shell 他,即可迂回避开直接 shell ie 造成的 pid 问题不符的问题。当然调用前要先设置代理服务器,用于设置了代理服务器,这个 exe 文件被 shell 的时候代理就生效了。经测试,同时shell 多个 exe 都没问题,而且都是不同的代理,从而解决了效率问题。如果大家有更好的办法,欢迎分享。
      

  9.   

    楼主你好,其实在VB或者VBA中,想起用IE的话,可以使用CreateObject("INTERNETEXPLORER.APPLICATION"),这个方法,然后打开网址的话,就用oIE.Navigate("http://your-url........")