【问题标题】:Use IDM (Internet Download Manager) API with Go在 Go 中使用 IDM(Internet 下载管理器)API
【发布时间】:2020-11-09 08:42:57
【问题描述】:

我正在尝试通过 Go 调用 idm api。查了Python和C#的实现,用Go写了一个demo,但是运行不起来,报如下错误,请问有大神可以告诉我原因,或者提供一个可以调用api的demo吗?

Exception 0xc0000005 0x0 0xffffffffffffffff 0x7ff973decc86
PC=0x7ff973decc86

syscall.Syscall9(0x7ff973e61f10, 0x9, 0x1c30f1a55f8, 0x1c30f1e0fe8, 0x1c30f1cb478, 0x1c30f1cb4f8, 0x1c30f1cb798, 0x1c30f1cb518, 0x1c30f1cb578, 0x1c30f1cba78, ...)
        C:/Go/src/runtime/syscall_windows.go:214 +0xf2
main.(*ICIDMLinkTransmitter).SendLinkToIDM(0x1c30f1d20e8, 0x1c30f1a55f8, 0x1c30f1e0fe8, 0x1c30f1cb478, 0x1c30f1cb4f8, 0x1c30f1cb798, 0x1c30f1cb518, 0x1c30f1cb578, 0x1c30f1cba78, 0x1c300000000, ...)
        C:/D/gocode/idm/main.go:52 +0x145
main.(*IDMLinkTransmitter).SendLinkToIDM(0xc000006028, 0xfdf9aa, 0x16, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, ...)
        C:/D/gocode/idm/main.go:97 +0x2fc
main.main()
        C:/D/gocode/idm/main.go:130 +0x105
rax     0x70007400740068
rbx     0x1082f80
rcx     0x69d75ffc60
rdi     0x3
rsi     0x69d75ffc60
rbp     0x69d75ffc30
rsp     0x69d75ff880
r8      0x3
r9      0x1c30f1cb4f8
r10     0x1c30f1d20e8
r11     0x1c30f1cba78
r12     0x11
r13     0x10
r14     0x1c30f1a55f8
r15     0x2030000
rip     0x7ff973decc86
rflags  0x10202
cs      0x33
fs      0x53
gs      0x2b
exit status 2

这是我的代码: https://github.com/Greyh4t/callidm

这里是 api 手册: http://www.internetdownloadmanager.com/support/idm_api.html

这里是 Python 的实现: Use IDM(Internet Download Manager) API with python

【问题讨论】:

    标签: go com system-calls idm


    【解决方案1】:

    几周后,我自己解决了这个问题。在研究了 c-code write-ups 之后,我发现发生错误是因为结构本身没有在 syscall 中传递。正确的代码如下。

    package idm
    
    import (
        "syscall"
        "unsafe"
    
        "github.com/lxn/win"
    )
    
    type ICIDMLinkTransmitter2Vtbl struct {
        QueryInterface uintptr
        AddRef         uintptr
        Release        uintptr
        SendLinkToIDM  uintptr
        SendLinkToIDM2 uintptr
        SendLinksArray uintptr
    }
    
    type ICIDMLinkTransmitter2 struct {
        vtbl *ICIDMLinkTransmitter2Vtbl
    }
    
    func (obj *ICIDMLinkTransmitter2) Release() uint32 {
        r1, _, _ := syscall.Syscall(
            obj.vtbl.Release,
            1,
            uintptr(unsafe.Pointer(obj)),
            0,
            0,
        )
    
        return uint32(r1)
    }
    
    func (obj *ICIDMLinkTransmitter2) SendLinkToIDM(url, referer, cookies, data, user, password,
        localPath, localFileName *uint16, flags int32) uint32 {
        r1, _, _ := syscall.Syscall12(
            obj.vtbl.SendLinkToIDM,
            10,
            uintptr(unsafe.Pointer(obj)),
            uintptr(unsafe.Pointer(url)),
            uintptr(unsafe.Pointer(referer)),
            uintptr(unsafe.Pointer(cookies)),
            uintptr(unsafe.Pointer(data)),
            uintptr(unsafe.Pointer(user)),
            uintptr(unsafe.Pointer(password)),
            uintptr(unsafe.Pointer(localPath)),
            uintptr(unsafe.Pointer(localFileName)),
            uintptr(flags),
            0,
            0,
        )
    
        return uint32(r1)
    }
    
    func (obj *ICIDMLinkTransmitter2) SendLinkToIDM2(url, referer, cookies, data, user, password,
        localPath, localFileName *uint16, flags int32, reserved1, reserved2 *win.VARIANT) uint32 {
        r1, _, _ := syscall.Syscall12(
            obj.vtbl.SendLinkToIDM2,
            12,
            uintptr(unsafe.Pointer(obj)),
            uintptr(unsafe.Pointer(url)),
            uintptr(unsafe.Pointer(referer)),
            uintptr(unsafe.Pointer(cookies)),
            uintptr(unsafe.Pointer(data)),
            uintptr(unsafe.Pointer(user)),
            uintptr(unsafe.Pointer(password)),
            uintptr(unsafe.Pointer(localPath)),
            uintptr(unsafe.Pointer(localFileName)),
            uintptr(flags),
            uintptr(unsafe.Pointer(reserved1)),
            uintptr(unsafe.Pointer(reserved2)),
        )
    
        return uint32(r1)
    }
    
    func (obj *ICIDMLinkTransmitter2) SendLinksArray(location *uint16, pLinksArray *win.VARIANT) uint32 {
        r1, _, _ := syscall.Syscall(
            obj.vtbl.SendLinksArray,
            3,
            uintptr(unsafe.Pointer(obj)),
            uintptr(unsafe.Pointer(location)),
            uintptr(unsafe.Pointer(pLinksArray)),
        )
    
        return uint32(r1)
    }
    

    完整代码在这里 https://github.com/Greyh4t/idm

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-12-15
      • 1970-01-01
      • 1970-01-01
      • 2017-08-22
      • 2013-08-27
      • 2020-11-10
      • 2016-01-06
      • 2018-06-10
      相关资源
      最近更新 更多