0

ActiveX Script在 SQl Server 上的作业中使用以下代码每 X 分钟调用一次 URL。

Dim WshShell
Set WshShell = CreateObject("WScript.Shell")
WshShell.Run "iexplore.exe http://www.google.com.br"
Set WsShell = Nothing

它正在工作,但创建的进程继续运行: 在此处输入图像描述

更改该代码以调用 URL 并终止最近调用的进程或使用“生存时间”调用它的任何方式。我认为它更安全,我不想杀死错误的进程。

4

4 回答 4

1

Following up on the suggestion by @Ted, you can also fetch a URL using native Microsoft capabilities in an in-process fashion. You can do this via a component known as WinHTTP (the latest appears to be WinHTTP 5.1).

See my script below which includes a function to simply obtain the status of a URL. When I run this script I get the following output:

http://www.google.com => 200 [OK]
http://www.google.com/does_not_exist => 404 [Not Found]
http://does_not_exist.google.com => -2147012889
    [The server name or address could not be resolved]

If you want the actual content behind a URL, try oHttp.ResponseText. Here's the WinHTTP reference if you are interested in other capabilities as well.

Option Explicit

Dim aUrlList
aUrlList = Array( _
    "http://www.google.com", _
    "http://www.google.com/does_not_exist", _
    "http://does_not_exist.google.com" _
)

Dim i
For i = 0 To UBound(aUrlList)
    WScript.Echo aUrlList(i) & " => " & GetUrlStatus(aUrlList(i))
Next

Function GetUrlStatus(sUrl)
    Dim oHttp : Set oHttp = CreateObject("WinHttp.WinHttpRequest.5.1")

    On Error Resume Next

    With oHttp
        .Open "GET", SUrl, False
        .Send
    End With

    If Err Then
        GetUrlStatus = Err.Number & " [" & Err.Description & "]"
    Else
        GetUrlStatus = oHttp.Status & " [" & oHttp.StatusText & "]"
    End If

    Set oHttp = Nothing
End Function
于 2012-08-24T13:49:16.293 回答
1

您启动 IE 的方式是外部的,一旦启动,您几乎无法控制该进程。更好的交互方式是这样的

Function GetData(strUrl) 'As String
  Set web = CreateObject("InternetExplorer.Application")
  web.Navigate strUrl
  Do While web.Busy
    wscript.sleep 100
  Loop
  Set doc = Nothing
  Do Until Not doc Is Nothing
    Set doc = web.Document
  Loop
  strWebPage = doc.all(1).innerHTML 'This does return the head sections
  web.Quit
  GetData = strWebPage
End Function


wscript.echo GetData("www.google.com")
于 2012-08-23T13:40:16.837 回答
1

更新:就目前而言,这似乎不是一个可行的解决方案。在多次调用之后,IE 进程也开始使用这种方法进行累积。看来这种行为与 IE 的会话管理有关。IE 不喜欢被突然终止。


我在这里找到了一些关于通过 WMI 管理进程的非常有用的信息。以此为基础,我想出了下面显示的代码。WMI 方法的优点之一是您可以访问该进程的唯一 ID。我认为我的代码是一个起点,因为我确信可以进一步改进(包括添加异常处理)。

也许对 WMI 有更深入了解的其他人可以提供额外的建议。

PS:希望你喜欢我将这个功能封装在一个名为Process.

Option Explicit

' Const PROG = "notepad.exe"
Const TARGET = "http://www.google.com"
Dim PROG : PROG = "C:\Program Files\Internet Explorer\iexplore.exe " & TARGET
Const ABOVE_NORMAL = 32768  ' what are the other priority constants?

Dim oProc : Set oProc = New Process
oProc.Name = PROG
' oProc.Priority = ABOVE_NORMAL
oProc.Launch

WScript.Echo "Launched '" & PROG & "' with process ID '" & oProc.ID & "'"
WScript.Sleep 5000
oProc.Terminate
WScript.Echo "Process " & oProc.ID & " killed."
Set oProc = Nothing

' ----------------------------------------------------------------------

Class Process

Public Computer
Public Name
Public Priority
Public ID
Public IsRunning

Private mHandle

Private Sub Class_Initialize()
    Me.Computer = "."
    Me.Name = Null
    Me.ID = -1
    Me.Priority = Null
    Me.IsRunning = False
    Set mHandle = Nothing
End Sub

Private Sub Class_Terminate()
    Set mHandle = Nothing
End Sub

Public Sub Launch()
    Dim oWmi, oStartup, oConfig
    Dim nPid

    Set oWmi = GetObject("winmgmts:" _
                         & "{impersonationLevel=impersonate}!\\" _
                         & Me.Computer & "\root\cimv2")

    Set oStartup = oWmi.Get("Win32_ProcessStartup")

    If Not IsNull(Me.Priority) Then
        Set oConfig = oStartup.SpawnInstance_
        oConfig.PriorityClass = Me.Priority
    End If

    Set mHandle = GetObject("winmgmts:root\cimv2:Win32_Process")
    mHandle.Create Me.Name, Null, oConfig, nPid
    ' WScript.Echo "TypeName Is [" & TypeName(mHandle) & "]"
    Me.ID = nPid
    Me.IsRunning = True
End Sub

Public Sub Terminate()
    ' mHandle.Terminate  ' hmmm, doesn't work...

    Dim oWmi
    Dim colProcessList, oProc

    Set oWmi = GetObject("winmgmts:" _
                                  & "{impersonationLevel=impersonate}!\\" _
                                  & Me.Computer & "\root\cimv2")

    Set colProcessList = oWmi.ExecQuery _
        ("Select * from Win32_Process Where ProcessId = '" & Me.ID & "'")

    For Each oProc In colProcessList  ' should be only one process
        ' WScript.Echo "TypeName Is [" & TypeName(oProc) & "]"
        oProc.Terminate
    Next

    Me.IsRunning = False
End Sub

End Class
于 2012-08-23T19:13:17.183 回答
1

您是否可以考虑使用轻量级的命令行 URL 检索程序,例如 CURL ( http://curl.haxx.se/docs/manpage.html ) 或 WGET ( http://www.gnu.org/software/wget/ )?这些程序可以很简单地从命令行执行:

wget http://www.google.com
curl http://www.google.com

您可以像这样从 VBScript 执行它们:

sub shell(cmd)
    ' Run a command as if you were running from the command line
    dim objShell
    Set objShell = WScript.CreateObject( "WScript.Shell" )
    objShell.Run(cmd)
    Set objShell = Nothing
end sub

shell "wget http://www.google.com"

唯一的缺点是 WGET 和 CURL 不会执行 javascript、下载附属图像或呈现 HTML;他们只会下载网页。根据我的经验,只要我只需要检索一个 HTML 页面,我就会经常使用 CURL 和 WGET;但如果我必须渲染某些东西或触发 AJAX 函数,我会使用可自动化的 Web 浏览器工具包,例如 Selenium、WATIN 或 IMacros。

于 2012-08-23T21:22:42.753 回答