4

A program I use runs .VBS scripts

So, in VBScript how can you handle the OnResponseFinished event for a WinHttpRequest object?

Set oHTTP = CreateObject("WinHttp.WinHttpRequest.5.1")
oHTTP.Open "GET", "http://www.google.com", True
oHTTP.Send
Carlos Gil
  • 593
  • 3
  • 10
  • 25
  • Where you able to make this work? I haven't found a way beside the one with `Error GoTo – Michael-O Aug 29 '12 at 12:33
  • There's a related question where binding to WinHttpRequest events using WScript.CreateObject() causes a GPF. Details can be found here http://stackoverflow.com/questions/27407533/wscript-createobject-crashes-windows-scripting-host-when-event-handler-prefix-is – jveazey Aug 19 '16 at 23:40

7 Answers7

3

I was trying to get some code executed when the winhttp response comes (using VBScript inside HTA file). You may consider putting your event code right after the send. Using the following code, the user interface does not hang when waiting for the response:

Set objHTTP = CreateObject("WinHttp.WinHttpRequest.5.1")
objHTTP.Open "GET", "http://www.google.com", True
objHTTP.Send
objHTTP.WaitForResponse 'pauses execution, but does not hang UI
'from now on, execution only takes effect after completion of the response:
msgbox objHTTP.responseText 'an example of what can be done with the response

This seems to be the same as synchronous winhttp for script files, which can be what you are looking for. So, the only difference may be noticed when using an user interface.

Alexey Malev
  • 6,408
  • 4
  • 34
  • 52
Eduardo Poço
  • 2,819
  • 1
  • 19
  • 27
1

Change the third paramater in the call to the Open method to false. Then place the code you would have in OnResponseFinished after the call to send.

AnthonyWJones
  • 187,081
  • 35
  • 232
  • 306
1

Use WScript's CreateObject not the built in one for event handler.

Set oHTTP = WScript.CreateObject(
    "WinHttp.WinHttpRequest.5.1",
    "oHTTP_"
)
Ana Pipo
  • 3
  • 3
Stephen Quan
  • 21,481
  • 4
  • 88
  • 75
0

It does need seem to be possible according to this (go to remarks) you can only access the error state with Err. Microsoft's documentation is lousy.

Michael-O
  • 18,123
  • 6
  • 55
  • 121
0

I found that I can get this to work Asynchronously by using the 'waitForResponse' with parameter '0' for the timeout method as a flag.

IE:

 oHTTP.Open "GET", "http://www.google.com", True
 oHTTP.Send

 Do While oHTTP.waitForResponse(0) = False
   'do stuff while waiting for it to be done

    WScript.Sleep 200 'sleep for 0.2 seconds between checks as not waste CPU 
    DoEvents
 Loop

 'Once the loop is exited, the response is finished
 MsgBox oHTTP.ResponseText
timonippon
  • 335
  • 1
  • 3
  • 10
0

I'll admit his isn't a great answer, but the usual way to register VBScript events is to use the GetRef function to get a reference to the event handler, eg with an MSXML2.XMLHTTP object:

Set oHTTP = CreateObject("MSXML2.XMLHTTP")
oHTTP.Open "GET", "http://www.google.com", True

oHTTP.OnReadyStateChange = GetRef("oHTTP_OnReadyStateChange")

Sub oHTTP_OnReadyStateChange
    ' do something
End sub

oHTTP.Send

The trouble is, I tried it for your code, ie

Set oHTTP = CreateObject("WinHttp.WinHttpRequest.5.1")
oHTTP.Open "GET", "http://www.google.com", True

oHTTP.OnResponseFinished = GetRef("oHTTP_OnResponseFinished")

Sub oHTTP_OnResponseFinished
    ' do something
End sub

oHTTP.Send

and it didn't work, getting the error

Object doesn't support this property or method: 'oHTTP.OnResponseFinished'

but perhaps this can give you a starting point , or maybe you can use the MSXML2 library instead?

Just updating this answer with the other way of handling COM events - use the second parameter for the CreateObject function which allows you to specify the function prefix which connects functions to objects, eg

Set oHTTP = CreateObject("WinHttp.WinHttpRequest.5.1", "oHTTP_")
oHTTP.Open "GET", "http://www.google.com", True

Sub oHTTP_OnResponseFinished
    ' do something
End sub

oHTTP.Send

unfortunately, this doesn't work either - it must be that the IWinHttpRequestEvents interface is inaccessible

  • hmm, it seem that you need access to the `IWinHttpRequestEvents` ([see here](http://msdn.microsoft.com/en-us/library/aa383925(v=vs.85).aspx)) interface and I don't think there's a way in VBScript to use an object's alternative interface –  Feb 26 '11 at 13:59
  • 1
    The problem is the XmlHttp OnReadyStateChange is specifically designed to receive function pointer from a scripting environment. Whereas OnResponseFinished is a standard COM Event, you can't just assign to it like a property. – AnthonyWJones Feb 26 '11 at 20:02
  • Thanks. I use this method for "MSXML2.XMLHTTP". In my case this isn't a stating point; it's where I got stuck. – Carlos Gil Feb 26 '11 at 22:11
0

I checked the Windows Registry and there appears to be a number of Microsoft objects that do nearly the same thing:

Microsoft.XMLHTTP {ED8C108E-4349-11D2-91A4-00C04F7969E8}
MSXML2.XMLHTTP {F6D90F16-9C73-11D3-B32E-00C04F990BB4}
WinHttp.WinHttpRequest.5.1 {2087c2f4-2cef-4953-a8ab-66779b670495}
MSXML2.ServerXMLHTTP {AFBA6B42-5692-48EA-8141-DC517DCF0EF1}

What works for me is Microsoft.ServerXMLHTTP which allows setting of the onreadystatechange in VBScript. The "MSXML2.ServerXMLHTTP" handles redirecting websites (e.g. google.com) which makes it a better choice over "Microsoft.XMLHTTP".

Dim xmlhttp ' global so can be accessed in OnStateChange

Sub OnStateChange
    If xmlhttp.readystate = 4 Then
        ' React to xmlhttp.responseText
        MsgBox xmlhttp.responseText
    End If
End Sub

Set xmlhttp = CreateObject("Microsoft.XMLHTTP")
xmlhttp.open "GET", "http://www.google.com/", true
xmlhttp.onreadystatechange = GetRef("OnStateChange")
xmlhttp.send
' do something else whilst xmlhttp is running in the background
MsgBox "Pausing so that OnStateChange can fire!"
Stephen Quan
  • 21,481
  • 4
  • 88
  • 75