AHK and API calls to Internet DOwnload Manager

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
rhodian
Posts: 13
Joined: 20 Nov 2019, 23:33

AHK and API calls to Internet DOwnload Manager

20 Nov 2019, 23:51

Hi,

I use Internet Download Manager (IDM) to download files from the internet and would like to have AHK communicate directly using its APIs.

I've contacted IDM support and they have provided me with www.internetdownloadmanager.com/support/idm_api.html but it is basically C++ specific examples with little in the way of actual API documentation and I'm having a hard time working out how to do it.

Can anyone help with AHK script examples on how to use SendLinksArray?

Thanks and regards
tmplinshi
Posts: 1604
Joined: 01 Oct 2013, 14:57

Re: AHK and API calls to Internet DOwnload Manager

22 Nov 2019, 00:46

Code: Select all

CLSID_CIDMLinkTransmitter := "{AC746233-E9D3-49CD-862F-068F7B7CCCA4}"
IID_ICIDMLinkTransmitter2 := "{94D09862-1875-4FC9-B434-91CF25C840A1}"
tbl := ComObjCreate(CLSID_CIDMLinkTransmitter, IID_ICIDMLinkTransmitter2)

; tbl.SendLinkToIDM
DllCall(vtable(tbl,3), "ptr", tbl
	, "str", "https://example.com" ; bstrUrl
	, "str", ""                    ; bstrReferer
	, "str", ""                    ; bstrCookies
	, "str", ""                    ; bstrData
	, "str", ""                    ; bstrUser
	, "str", ""                    ; bstrPassword
	, "str", ""                    ; bstrLocalPath
	, "str", ""                    ; bstrLocalFileName
	, "int", 0)                    ; lFlags

MsgBox
; tbl.SendLinksArray
pLinksArray := ComObjArray(VT_BSTR:=8, 2, 4)
pLinksArray[0, 0] := "https://example.com"
pLinksArray[1, 0] := "https://bing.com"
DllCall(vtable(tbl,5), "ptr", tbl, "str", "", "ptr", ComObjValue(pLinksArray))

ObjRelease(tbl)
return

vtable(ptr, n) {
    ; NumGet(ptr+0) returns the address of the object's virtual function
    ; table (vtable for short). The remainder of the expression retrieves
    ; the address of the nth function's address from the vtable.
    return NumGet(NumGet(ptr+0), n*A_PtrSize)
}
I got SendLinkToIDM to work, but not SendLinksArray..
swagfag
Posts: 6222
Joined: 11 Jan 2017, 17:59

Re: AHK and API calls to Internet DOwnload Manager

22 Nov 2019, 02:53

maybe u have to sysalloc the strings
rhodian
Posts: 13
Joined: 20 Nov 2019, 23:33

Re: AHK and API calls to Internet DOwnload Manager

23 Nov 2019, 08:54

tmplinshi wrote:
22 Nov 2019, 00:46

Code: Select all

CLSID_CIDMLinkTransmitter := "{AC746233-E9D3-49CD-862F-068F7B7CCCA4}"
IID_ICIDMLinkTransmitter2 := "{94D09862-1875-4FC9-B434-91CF25C840A1}"
tbl := ComObjCreate(CLSID_CIDMLinkTransmitter, IID_ICIDMLinkTransmitter2)

; tbl.SendLinkToIDM
DllCall(vtable(tbl,3), "ptr", tbl
	, "str", "https example.com "  Broken Link for safety ; bstrUrl
	, "str", ""                    ; bstrReferer
	, "str", ""                    ; bstrCookies
	, "str", ""                    ; bstrData
	, "str", ""                    ; bstrUser
	, "str", ""                    ; bstrPassword
	, "str", ""                    ; bstrLocalPath
	, "str", ""                    ; bstrLocalFileName
	, "int", 0)                    ; lFlags

MsgBox
; tbl.SendLinksArray
pLinksArray := ComObjArray(VT_BSTR:=8, 2, 4)
pLinksArray[0, 0] := "https example.com "  Broken Link for safety
pLinksArray[1, 0] := "https bing.com "  Broken Link for safety
DllCall(vtable(tbl,5), "ptr", tbl, "str", "", "ptr", ComObjValue(pLinksArray))

ObjRelease(tbl)
return

vtable(ptr, n) {
    ; NumGet(ptr+0) returns the address of the object's virtual function
    ; table (vtable for short). The remainder of the expression retrieves
    ; the address of the nth function's address from the vtable.
    return NumGet(NumGet(ptr+0), n*A_PtrSize)
}
I got SendLinkToIDM to work, but not SendLinksArray..
Thanks, I'll give it a go...
rhodian
Posts: 13
Joined: 20 Nov 2019, 23:33

Re: AHK and API calls to Internet DOwnload Manager

23 Nov 2019, 11:43

After fiddling around with the code, I wasn't able to get SendLinksArray to work either so I relented on using multiple SendLinktoIDM calls instead.

What I found was that with long bstrUrl strings the URL was being truncated e.g. https[colon]//download.microsoft.com/download/1/7/1/1718CCC4-6315-4D8E-9543-8E28A4E18C4C/dxwebsetup.exe, the filename was incorrectly set to 1718CCC4-63 instead of dxwebsetup.exe. As a result the file was not being found.

WT?
tmplinshi
Posts: 1604
Joined: 01 Oct 2013, 14:57

Re: AHK and API calls to Internet DOwnload Manager

23 Nov 2019, 22:35

Thanks swagfag, SysAllocString function can fix the truncated issue :)

Code: Select all

CLSID_CIDMLinkTransmitter := "{AC746233-E9D3-49CD-862F-068F7B7CCCA4}"
IID_ICIDMLinkTransmitter2 := "{94D09862-1875-4FC9-B434-91CF25C840A1}"
tbl := ComObjCreate(CLSID_CIDMLinkTransmitter, IID_ICIDMLinkTransmitter2)

bstrUrl := SysAllocString("https://download.microsoft.com/download/1/7/1/1718CCC4-6315-4D8E-9543-8E28A4E18C4C/dxwebsetup.exe")
DllCall(vtable(tbl,3), ptr,tbl, ptr,bstrUrl, ptr,0, ptr,0, ptr,0, ptr,0, ptr,0, ptr,0, ptr,0, int,0) ; tbl.SendLinkToIDM

SysFreeString(bstrUrl)
ObjRelease(tbl)
return

SysAllocString(str) {
	return DllCall("oleaut32\SysAllocString", "str", str, "ptr")
}

SysFreeString(pBstr) {
	DllCall("oleaut32\SysFreeString", "ptr", pBstr)
}

vtable(ptr, n) {
	; NumGet(ptr+0) returns the address of the object's virtual function
	; table (vtable for short). The remainder of the expression retrieves
	; the address of the nth function's address from the vtable.
	return NumGet(NumGet(ptr+0), n*A_PtrSize)
}
rhodian
Posts: 13
Joined: 20 Nov 2019, 23:33

Re: AHK and API calls to Internet DOwnload Manager

24 Nov 2019, 00:50

tmplinshi wrote:
23 Nov 2019, 22:35
Thanks swagfag, SysAllocString function can fix the truncated issue :)

Code: Select all

CLSID_CIDMLinkTransmitter := "{AC746233-E9D3-49CD-862F-068F7B7CCCA4}"
IID_ICIDMLinkTransmitter2 := "{94D09862-1875-4FC9-B434-91CF25C840A1}"
tbl := ComObjCreate(CLSID_CIDMLinkTransmitter, IID_ICIDMLinkTransmitter2)

bstrUrl := SysAllocString("https download.microsoft.com /download/1/7/1/1718CCC4-6315-4D8E-9543-8E28A4E18C4C/dxwebsetup.exe")  Broken Link for safety
DllCall(vtable(tbl,3), ptr,tbl, ptr,bstrUrl, ptr,0, ptr,0, ptr,0, ptr,0, ptr,0, ptr,0, ptr,0, int,0) ; tbl.SendLinkToIDM

SysFreeString(bstrUrl)
ObjRelease(tbl)
return

SysAllocString(str) {
	return DllCall("oleaut32\SysAllocString", "str", str, "ptr")
}

SysFreeString(pBstr) {
	DllCall("oleaut32\SysFreeString", "ptr", pBstr)
}

vtable(ptr, n) {
	; NumGet(ptr+0) returns the address of the object's virtual function
	; table (vtable for short). The remainder of the expression retrieves
	; the address of the nth function's address from the vtable.
	return NumGet(NumGet(ptr+0), n*A_PtrSize)
}
Thanks, using SysAllocString worked for SendLinkToIDM, it didn't do anything for SendLinksArray. I've got a way forward!
malcev
Posts: 1769
Joined: 12 Aug 2014, 12:37

Re: AHK and API calls to Internet DOwnload Manager

03 May 2020, 20:14

SendLinksArray will work if You create and fill SafeArray manually, like this:

Code: Select all

VarSetCapacity(SAFEARRAYBOUND, 16, 0)
NumPut(2, SAFEARRAYBOUND, 0, "uint")   ; cElements
NumPut(4, SAFEARRAYBOUND, 8, "uint")   ; cElements
pSA := DllCall("OleAut32\SafeArrayCreate", "ushort", VT_BSTR := 8, "uint", 2, "ptr", &SAFEARRAYBOUND, "ptr")

referer := SysAllocString("http://www.internetdownloadmanager.com/")
href1 := SysAllocString("http://www.internetdownloadmanager.com/trans_kit.zip")
cookie1 := SysAllocString("cookie1=aaa")
descr1 := SysAllocString("Link 1")
href2 := SysAllocString("http://www.internetdownloadmanager.com/idman406.exe")
cookie2 := SysAllocString("cookie2=bbb")
descr2 := SysAllocString("Link 2")
userAgent := SysAllocString("User-Agent test2")

VarSetCapacity(rgIndices, 8, 0)
DllCall("OleAut32\SafeArrayPutElement", "ptr", pSA, "ptr", &rgIndices, "ptr", href1, "uint")
NumPut(1, rgIndices, 4, "int")
DllCall("OleAut32\SafeArrayPutElement", "ptr", pSA, "ptr", &rgIndices, "ptr", cookie1, "uint")
NumPut(2, rgIndices, 4, "int")
DllCall("OleAut32\SafeArrayPutElement", "ptr", pSA, "ptr", &rgIndices, "ptr", descr1, "uint")
NumPut(3, rgIndices, 4, "int")
DllCall("OleAut32\SafeArrayPutElement", "ptr", pSA, "ptr", &rgIndices, "ptr", userAgent, "uint")
VarSetCapacity(rgIndices, 8, 0)
NumPut(1, rgIndices, 0, "int")
DllCall("OleAut32\SafeArrayPutElement", "ptr", pSA, "ptr", &rgIndices, "ptr", href2, "uint")
NumPut(1, rgIndices, 4, "int")
DllCall("OleAut32\SafeArrayPutElement", "ptr", pSA, "ptr", &rgIndices, "ptr", cookie2, "uint")
NumPut(2, rgIndices, 4, "int")
DllCall("OleAut32\SafeArrayPutElement", "ptr", pSA, "ptr", &rgIndices, "ptr", descr2, "uint")
NumPut(3, rgIndices, 4, "int")
DllCall("OleAut32\SafeArrayPutElement", "ptr", pSA, "ptr", &rgIndices, "ptr", 0, "uint")

CLSID_CIDMLinkTransmitter := "{AC746233-E9D3-49CD-862F-068F7B7CCCA4}"
IID_ICIDMLinkTransmitter2 := "{94D09862-1875-4FC9-B434-91CF25C840A1}"
tbl := ComObjCreate(CLSID_CIDMLinkTransmitter, IID_ICIDMLinkTransmitter2)
VarSetCapacity(variant, 8+A_PtrSize*2, 0)
NumPut(0x2000|8, variant, 0, "ushort")   ; VT_ARRAY | VT_BSTR
NumPut(pSA, variant, 8, "ptr")
DllCall(NumGet(NumGet(tbl+0)+5*A_PtrSize), "ptr", tbl, "ptr", referer, "ptr", &variant)
DllCall("OleAut32\SafeArrayDestroy", "ptr", pSA)
ObjRelease(tbl)
return

SysAllocString(str) {
	return DllCall("oleaut32\SysAllocString", "str", str, "ptr")
}
With ComObjArray You can do it like this.

Code: Select all

...
VarSetCapacity(variant, 8+A_PtrSize*2, 0)
NumPut(0x2000|8, variant, 0, "ushort")   ; VT_ARRAY | VT_BSTR
NumPut(ComObjValue(pLinksArray), variant, 8, "ptr")
DllCall(vtable(tbl,5), "ptr", tbl, "str", "", "ptr", &variant)

Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: Bing [Bot], peter_ahk and 199 guests