AutoHotkey Community

It is currently May 27th, 2012, 1:00 pm

All times are UTC [ DST ]




Post new topic Reply to topic  [ 12 posts ] 
Author Message
PostPosted: October 26th, 2011, 3:46 am 
Offline

Joined: March 27th, 2008, 2:14 pm
Posts: 700
The following code causes the script to crash every time:
Code:
url := "http://google.com/search?q=test"

x := new WinHttpRequest()
x.whr.Open("GET", url, true) ;it still crashes with false, but it's easier to see in asynchronous mode
x.whr.Send()
MsgBox wait for a sec

class WinHttpRequest
{
    __New()
    {
        this.whr := ComObjCreate("WinHttp.WinHttpRequest.5.1")

        ; if this line is commented out, it doesn't crash
        ComObjConnect(This.whr,WinHttpRequest)
    }
}

_________________
Scripts - License


Last edited by infogulch on October 26th, 2011, 9:57 pm, edited 1 time in total.

Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: October 26th, 2011, 5:32 pm 
Offline
User avatar

Joined: May 24th, 2009, 5:35 am
Posts: 2099
Location: Iowa, USA
It seems to be crashing when connecting the WinHttpRequest object in general:
Code:
url := "http://google.com/search?q=test"

whr := ComObjCreate("WinHttp.WinHttpRequest.5.1")
ComObjConnect(whr, "_") ; works fine w/o this line
whr.Open("GET", url)
whr.Send()
MsgBox, % whr.responsetext


Tested on AHK Basic for good measure. Seems connecting to the WinHttpRequest messes things up for some reason:
Code:
Com_Init()

url := "http://google.com/search?q=test"

whr := Com_CreateObject("WinHttp.WinHttpRequest.5.1")
sink := Com_ConnectObject(whr, "_") ; works fine w/o this line
Com_Invoke(whr, "Open", "GET", url)
Com_Invoke(whr, "Send") ; <--- ERROR:   The COM Object may not be a valid Dispatch Object!
MsgBox, % Com_Invoke(whr, "responsetext")

Com_DisconnectObject(sink), Com_Release(whr), Com_Term()


Tested on WIN XP SP3

_________________
Image
Recommended: AutoHotkey_L
Basic Webpage Controls


Last edited by jethrow on October 26th, 2011, 6:27 pm, edited 1 time in total.

Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: October 26th, 2011, 5:47 pm 
Offline
User avatar

Joined: March 19th, 2008, 12:43 am
Posts: 5482
Location: the tunnel(?=light)
I'm guessing that's not an appropriate usage of the prefix parameter.

_________________
Image
Try Quick Search for Autohotkey or see the tutorial for newbies.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: October 26th, 2011, 6:55 pm 
Offline

Joined: March 27th, 2008, 2:14 pm
Posts: 700
ComObjConnect() prefix param wrote:
[v1.1.01+]: This parameter can be an object defined by the script. When an event is raised, the corresponding method is called. ...


Also, it doesn't matter if the functions / methods exist or not, it still crashes.


Edit:
void OnResponseDataAvailable(
    [in] SAFEARRAY(unsigned char) *Data
);


Maybe ahk isn't expecting a safearray as a param?

_________________
Scripts - License


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: October 26th, 2011, 11:00 pm 
Offline
User avatar

Joined: May 24th, 2009, 5:35 am
Posts: 2099
Location: Iowa, USA
I tested this in Ruby & it's crashing as well:
Code:
require "WIN32OLE"

url = 'http://google.com/search?q=test'
whr = WIN32OLE.new('WinHttp.WinHttpRequest.5.1')
event = WIN32OLE_EVENT.new(whr) # works fine w/o this line
whr.Open("GET", url)
whr.Send()
puts whr.responsetext
gets

I would like to see some tests in VBScript or JScript (or even AutoIt), but this may not be an AHK bug.

_________________
Image
Recommended: AutoHotkey_L
Basic Webpage Controls


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: October 26th, 2011, 11:02 pm 
Offline

Joined: March 27th, 2008, 2:14 pm
Posts: 700
Well... that kinda sucks. At least it's not an ahk bug, but there went our only chance that it could be fixed. :lol:

_________________
Scripts - License


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: October 26th, 2011, 11:05 pm 
Offline

Joined: October 17th, 2006, 4:15 pm
Posts: 7503
Location: Australia
ComObjConnect uses late-bound events; i.e. IDispatch. WinHttpRequest uses the IWinHttpRequestEvent interface, which derives directly from IUnkown and is therefore incompatible with ComObjConnect. Ordinarily the event sink object's QueryInterface method should not respond to an unsupported interface, but AutoHotkey also responds to the default event source interface of the object it is connected to (which is what it gets method names from). This is safe (only) for dispatch interfaces (dispinterface) with no non-dispatch methods.
Code:
STDMETHODIMP ComEvent::QueryInterface(REFIID riid, void **ppv)
{
   if (riid == mIID || riid == IID_IDispatch || riid == IID_IUnknown)
   {
      AddRef();
      *ppv = this;
      return S_OK;
   }
   else
   {
      *ppv = NULL;
      return E_NOINTERFACE;
   }
}

I was always a bit suspicious of this, but I supposed it might be necessary in some cases. Below is a test release which excludes the check in red (i.e. only responds to IUnknown and IDispatch). It appears to work with IE9's WebBrowser object, but needs to be tested with as many other types of objects as possible.
If this fails in some cases where previous releases work, I think there are three ways it could go:
  • Ignore the incompatibility; let the script crash if an incompatible interface is needed.
  • If the event source interface contains non-dispatch methods, return E_NOINTERFACE when that interface is requested. If the interface has dispatch methods as well, it might still work via IDispatch.
  • Manually reconstruct the interface/vtable based on known type information. This would allow WinHttpRequest and other objects which use non-IDispatch event sources to work. (I am unlikely to take this route due to complexity.)


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: October 26th, 2011, 11:23 pm 
Offline

Joined: March 27th, 2008, 2:14 pm
Posts: 700
Stupidity edited out: Yay it doesn't crash now! I'll try it on a few objects i know.

Quote:
Manually reconstruct the interface/vtable based on known type information.
By this I'm guessing you mean inferring the arg types dynamically?

What if the interface/vtable was constructed based on user input? E.g. pass an object to ComObjConnect() that describes the arg types. If the user specifies inaccurate information then a script crash is their own fault.
Code:
ComObjConnect(cobj, "", {OnError: ["long", "BSTR"]})


I may be misunderstanding the problem.

_________________
Scripts - License


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: October 27th, 2011, 4:26 am 
Offline

Joined: October 17th, 2006, 4:15 pm
Posts: 7503
Location: Australia
ComObjConnect already retrieves the ITypeInfo of the event source interface in order to convert incoming member IDs to names. ITypeInfo can be used to determine the name and offset of each method and the types of its parameters more reliably than if they were provided by the user. However, this information needs to be used to construct a callback for each method, to convert the parameters and route the method call to the appropriate object. Each callback would be placed at a particular offset within the vtable. The ComEvent object would contain a field which contains a pointer to the vtable and ComEvent::QueryInterface would return a pointer to this field (i.e. the "interface pointer"). Since the offset of the field is known at compile-time, the address of the ComEvent object would be calculated from the interface pointer which is passed in the method call.

Dispatch interfaces are much easier: the caller specifies which method they're calling and what the type and value of each parameter is (via the VARIANTARG structure). AutoHotkey already has routines for converting each VARIANT or VARIANTARG to an appropriate script-usable value, but I think that additional types not handled by those routines may be used by non-dispatch interfaces. Each dispatch interface has the same binary interface (IDispatch), so there's no need for anything tricky (like constructing callbacks using machine code).

For WinHttpRequest, perhaps someone would like to update Sean's example script.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: October 27th, 2011, 4:48 am 
Offline

Joined: March 27th, 2008, 2:14 pm
Posts: 700
So essentially, all Dispatch events can be handled dynamically in one interface, but non-IDispatch interfaces require a different compiled method for each event and pointers to them put in vtable.

So to implement non-IDispatch events in ahk you would need to dynamically construct callbacks in machine code and put their pointers into vtable.

... sounds like a pain in the a** :lol:

[Moderator's note: Topic split to WinHttpRequest async in AutoHotkey_L]

_________________
Scripts - License


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: October 29th, 2011, 5:45 am 
Offline
User avatar

Joined: May 24th, 2009, 5:35 am
Posts: 2099
Location: Iowa, USA
Lexikos wrote:
Below is a test release ... but needs to be tested with as many other types of objects as possible.

Seems to be working fine with MS Office - I assume checking the Application Object is sufficient? However, ComObjConnect is giving an error on WMP:
Code:
FileSelectFile, file, 2, %A_MyDocuments%, Select WMP Compatable File:
if Errorlevel
   ExitApp

wmp := ComObjCreate("WMPlayer.OCX")
ComObjConnect(wmp, new Event)
wmp.url := file ; play file


class Event {
   __New() {
      Gui, +AlwaysOnTop +ToolWindow
      Gui, Add, ListView, x2 y10 w160 h680, Event Name
      Gui, Show, x10 y10 w170 h700, Events
      return, this
      GuiClose:
      try ExitApp
   }
   __Call(p*) {
      LV_Insert(1,"Col1",p[1])
   }
}

_________________
Image
Recommended: AutoHotkey_L
Basic Webpage Controls


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: November 21st, 2011, 1:54 am 
Offline

Joined: October 17th, 2006, 4:15 pm
Posts: 7503
Location: Australia
v1.1.05.02 has been released.
Quote:
Fixed ComObjConnect to filter out non-dispatch interfaces instead of allowing the script to crash.


Report this post
Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 12 posts ] 

All times are UTC [ DST ]


Who is online

Users browsing this forum: No registered users and 1 guest


You can post new topics in this forum
You can reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Powered by phpBB® Forum Software © phpBB Group