[AHK] WinHttpRequest.5.1报错 0x80092004 找不到对象或属性

目录

背景描述

用浏览器访问,正常返回

​编辑

[AHK v2官方示例源代码](#AHK v2官方示例源代码)

[AHK v2运行结果报错(0x80092004) 找不到对象或属性](#AHK v2运行结果报错(0x80092004) 找不到对象或属性)

[用thqby大佬的WinHttpRequest.ahk库测试报错 0x80092004 找不到对象或属性](#用thqby大佬的WinHttpRequest.ahk库测试报错 0x80092004 找不到对象或属性)

附:

用Apifox访问,也正常返回

[AHK v1 官方示例源代码](#AHK v1 官方示例源代码)

[AHK v1运行失败报错 0x80092004 找不到对象或属性](#AHK v1运行失败报错 0x80092004 找不到对象或属性)

用Msxml2.XMLHTTP则能正常得到结果



背景描述

想通过ahk编程,获取 https://autohotkey.com/download/2.0/version.txt 的文件内容。

在确认用浏览器可以正常访问情况下,用官方帮助中的示例运行会报错 Error: (0x80092004) 找不到对象或属性。用 thqby大佬的 WinHttpRequest.ahk 网络请求库 https://github.com/thqby/ahk2_lib/blob/master/WinHttpRequest.ahk 也报同样错误。

求指点

用浏览器访问,正常返回

AHK v2官方示例源代码

javascript 复制代码
whr := ComObject("WinHttp.WinHttpRequest.5.1")
whr.Open("GET", "https://autohotkey.com/download/2.0/version.txt", true)
whr.Send()
whr.WaitForResponse()
version := whr.ResponseText
MsgBox version

AHK v2运行结果报错(0x80092004) 找不到对象或属性

如果把参数 true改为 false ,报错如下:

用thqby大佬的WinHttpRequest.ahk库测试报错 0x80092004 找不到对象或属性

javascript 复制代码
/************************************************************************
 * @file: WinHttpRequest.ahk
 * @description: 网络请求库
 * @author thqby
 * @date 2021/08/01
 * @version 0.0.18
 ***********************************************************************/
 #Requires AutoHotkey v2.0
whr := WinHttpRequest()
whr.Open("Get", "https://www.autohotkey.com/download/2.0/version.txt", True)
whr.Send()
whr.WaitForResponse()
MsgBox whr.ResponseText


class WinHttpRequest {
	static AutoLogonPolicy := {
		Always: 0,
		OnlyIfBypassProxy: 1,
		Never: 2
	}
	static Option := {
		UserAgentString: 0,
		URL: 1,
		URLCodePage: 2,
		EscapePercentInURL: 3,
		SslErrorIgnoreFlags: 4,
		SelectCertificate: 5,
		EnableRedirects: 6,
		UrlEscapeDisable: 7,
		UrlEscapeDisableQuery: 8,
		SecureProtocols: 9,
		EnableTracing: 10,
		RevertImpersonationOverSsl: 11,
		EnableHttpsToHttpRedirects: 12,
		EnablePassportAuthentication: 13,
		MaxAutomaticRedirects: 14,
		MaxResponseHeaderSize: 15,
		MaxResponseDrainSize: 16,
		EnableHttp1_1: 17,
		EnableCertificateRevocationCheck: 18,
		RejectUserpwd: 19
	}
	static PROXYSETTING := {
		PRECONFIG: 0,
		DIRECT: 1,
		PROXY: 2
	}
	static SETCREDENTIALSFLAG := {
		SERVER: 0,
		PROXY: 1
	}
	static SecureProtocol := {
		SSL2: 0x08,
		SSL3: 0x20,
		TLS1: 0x80,
		TLS1_1: 0x200,
		TLS1_2: 0x800,
		All: 0xA8
	}
	static SslErrorFlag := {
		UnknownCA: 0x0100,
		CertWrongUsage: 0x0200,
		CertCNInvalid: 0x1000,
		CertDateInvalid: 0x2000,
		Ignore_All: 0x3300
	}

	__New(UserAgent := unset) {
		(this.whr := ComObject('WinHttp.WinHttpRequest.5.1')).Option[0] := IsSet(UserAgent) ? UserAgent : 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.114 Safari/537.36 Edg/89.0.774.68'
	}

	request(url, method := 'GET', post_data?, headers := {}) {
		this.Open(method, url)
		for k, v in headers.OwnProps()
			this.SetRequestHeader(k, v)
		this.Send(post_data?)
		return this.ResponseText
	}
	enableRequestEvents(Enable := true) {
		static vtable := init_vtable()
		if !Enable
			return this._ievents := this._ref := 0
		if this._ievents
			return
		IConnectionPointContainer := ComObjQuery(pwhr := ComObjValue(this.whr), '{B196B284-BAB4-101A-B69C-00AA00341D07}')
		DllCall('ole32\CLSIDFromString', 'str', '{F97F4E15-B787-4212-80D1-D380CBBF982E}', 'ptr', IID_IWinHttpRequestEvents := Buffer(16))
		ComCall(4, IConnectionPointContainer, 'ptr', IID_IWinHttpRequestEvents, 'ptr*', IConnectionPoint := ComValue(0xd, 0))	; IConnectionPointContainer->FindConnectionPoint
		IWinHttpRequestEvents := Buffer(3 * A_PtrSize)
		NumPut('ptr', vtable.Ptr, 'ptr', ObjPtr(this), 'ptr', ObjPtr(IWinHttpRequestEvents), IWinHttpRequestEvents)
		ComCall(5, IConnectionPoint, 'ptr', IWinHttpRequestEvents, 'uint*', &dwCookie := 0)	; IConnectionPoint->Advise
		this._ievents := { __Delete: (*) => ComCall(6, IConnectionPoint, 'uint', dwCookie) }
		static init_vtable() {
			vtable := Buffer(A_PtrSize * 7), offset := vtable.Ptr
			for nParam in StrSplit('3113213')
				offset := NumPut('ptr', CallbackCreate(EventHandler.Bind(A_Index), , Integer(nParam)), offset)
			vtable.DefineProp('__Delete', { call: __Delete })
			return vtable
			static EventHandler(index, this, arg1 := 0, arg2 := 0) {
				if (index < 4) {
					IEvents := NumGet(this, A_PtrSize * 2, 'ptr')
					if index == 1
						NumPut('ptr', this, arg2)
					if index == 3
						ObjRelease(IEvents)
					else ObjAddRef(IEvents)
					return 0
				}
				req := ObjFromPtrAddRef(NumGet(this, A_PtrSize, 'ptr'))
				req.readyState := index - 2
				switch index {
					case 4:	; OnResponseStart
						try req.OnResponseStart(arg1, StrGet(arg2, 'utf-16'))
					case 5:	; OnResponseDataAvailable
						try req.OnResponseDataAvailable(
							NumGet((pSafeArray := NumGet(arg1, 'ptr')) + 8 + A_PtrSize, 'ptr'),
							NumGet(pSafeArray + 8 + A_PtrSize * 2, 'uint'))
					case 6:	; OnResponseFinished
						try req._ref := 0, req.OnResponseFinished()
					case 7:	; OnError
						try req.readyState := req._ref := 0, req.OnError(arg1, StrGet(arg2, 'utf-16'))
				}
			}
			static __Delete(this) {
				loop 7
					CallbackFree(NumGet(this, (A_Index - 1) * A_PtrSize, 'ptr'))
			}
		}
	}

	;#region IWinHttpRequest https://learn.microsoft.com/en-us/windows/win32/winhttp/iwinhttprequest-interface
	SetProxy(ProxySetting, ProxyServer, BypassList) => this.whr.SetProxy(ProxySetting, ProxyServer, BypassList)
	SetCredentials(UserName, Password, Flags) => this.whr.SetCredentials(UserName, Password, Flags)
	SetRequestHeader(Header, Value) => this.whr.SetRequestHeader(Header, Value)
	GetResponseHeader(Header) => this.whr.GetResponseHeader(Header)
	GetAllResponseHeaders() => this.whr.GetAllResponseHeaders()
	Send(Body?) => (this._ievents && this._ref := this, this.whr.Send(Body?))
	Open(verb, url, async := false) {
		this.readyState := 0
		this.whr.Open(verb, url, async)
		this.readyState := 1
	}
	WaitForResponse(Timeout := -1) => this.whr.WaitForResponse(Timeout)
	Abort() => (this._ref := this.readyState := 0, this.whr.Abort())
	SetTimeouts(ResolveTimeout := 0, ConnectTimeout := 60000, SendTimeout := 30000, ReceiveTimeout := 30000) => this.whr.SetTimeouts(ResolveTimeout, ConnectTimeout, SendTimeout, ReceiveTimeout)
	SetClientCertificate(ClientCertificate) => this.whr.SetClientCertificate(ClientCertificate)
	SetAutoLogonPolicy(AutoLogonPolicy) => this.whr.SetAutoLogonPolicy(AutoLogonPolicy)

	Status => this.whr.Status
	StatusText => this.whr.StatusText
	ResponseText => this.whr.ResponseText
	ResponseBody {
		get {
			pSafeArray := ComObjValue(t := this.whr.ResponseBody)
			pvData := NumGet(pSafeArray + 8 + A_PtrSize, 'ptr')
			cbElements := NumGet(pSafeArray + 8 + A_PtrSize * 2, 'uint')
			return ClipboardAll(pvData, cbElements)
		}
	}
	ResponseStream => this.whr.responseStream
	Option[Opt] {
		get => this.whr.Option[Opt]
		set => (this.whr.Option[Opt] := Value)
	}
	Headers {
		get {
			m := Map(), m.Default := ''
			loop parse this.GetAllResponseHeaders(), '`r`n'
				if (p := InStr(A_LoopField, ':'))
					m[SubStr(A_LoopField, 1, p - 1)] .= LTrim(SubStr(A_LoopField, p + 1))
			return m
		}
	}
	/**
	 * The OnError event occurs when there is a run-time error in the application.
	 * @prop {(this,errCode,errDesc)=>void} OnError
	 */
	OnError := 0
	/**
	 * The OnResponseDataAvailable event occurs when data is available from the response.
	 * @prop {(this,safeArray)=>void} OnResponseDataAvailable
	 */
	OnResponseDataAvailable := 0
	/**
	 * The OnResponseStart event occurs when the response data starts to be received.
	 * @prop {(this,status,contentType)=>void} OnResponseDataAvailable
	 */
	OnResponseStart := 0
	/**
	 * The OnResponseFinished event occurs when the response data is complete.
	 * @prop {(this)=>void} OnResponseDataAvailable
	 */
	OnResponseFinished := 0
	;#endregion

	readyState := 0, whr := 0, _ievents := 0
	static __New() {
		if this != WinHttpRequest
			return
		this.DeleteProp('__New')
		for prop in ['OnError', 'OnResponseDataAvailable', 'OnResponseStart', 'OnResponseFinished']
			this.Prototype.DefineProp(prop, { set: make_setter(prop) })
		make_setter(prop) => (this, value := 0) => value && (this.DefineProp(prop, { call: value }), this.enableRequestEvents())
	}
}

附:

用Apifox访问,也正常返回

AHK v1 官方示例源代码

javascript 复制代码
whr := ComObjCreate("WinHttp.WinHttpRequest.5.1")
whr.Open("GET", "https://www.autohotkey.com/download/1.1/version.txt", true)
whr.Send()
whr.WaitForResponse()
version := whr.ResponseText
MsgBox % version

AHK v1运行失败报错 0x80092004 找不到对象或属性

用Msxml2.XMLHTTP则能正常得到结果

javascript 复制代码
#Requires AutoHotkey v2.0
req := ComObject("Msxml2.XMLHTTP")
req.open("GET", "https://www.autohotkey.com/download/2.0/version.txt", true)
req.onreadystatechange := Ready
req.send()

Persistent

Ready() {
    if (req.readyState != 4)  ; 没有完成.
        return
    if (req.status == 200) ; OK.
        MsgBox "Latest AutoHotkey version: " req.responseText
    else
        MsgBox "Status " req.status,, 16
    ExitApp
}
相关推荐
小Mie不吃饭4 个月前
AHK是让任何软件都支持 Shift + 鼠标滚轮 实现界面水平滚动
vscode·sublime text·记事本·autohotkey·shift+滚轮·水平滚动·高效快捷
也好先生4 个月前
AutoHotKey自动热键(十一)下载SciTE4AutoHotkey-Plus的中文增强版脚本编辑器
自动化·编辑器·计算机外设·快捷键·autohotkey·windows热键
也好先生4 个月前
AutoHotKey自动热键(七)WINDOWS按键映射与鼠标映射(替换/组合)
自动化·计算机外设·快捷键·autohotkey·windows热键·脚本热键·鼠标键盘映射
liuyukuan4 个月前
[AHK V2]SQLite测试用例
数据库·sqlite·ahk·autohotkey
也好先生5 个月前
AutoHotKey自动热键(二)中文版帮助手册下载和自定义一般键盘快捷键
计算机外设·autohotkey
飞跃-5 个月前
AHK的对象和类学习心得
autohotkey
liuyukuan5 个月前
[AHK V2]鼠标悬停展开窗口,鼠标离开折叠窗口
ahk·autohotkey·v2
liuyukuan8 个月前
【AHK v2】数据结构LinkedList实现示例
数据结构·ahk·autohotkey·v2
开开心心写Bug1 年前
ahk系列-windows超级运行框-表达式计算(11)—avg /sum 平均求和
windows·求和·autohotkey·平均值·运行框