Wininet.dll 在提取 cookie 时崩溃 excel 64 位

Posted

技术标签:

【中文标题】Wininet.dll 在提取 cookie 时崩溃 excel 64 位【英文标题】:Wininet.dll crashes excel 64 bit when extracting cookies 【发布时间】:2021-10-05 16:00:49 【问题描述】:

我的公司从 32 位 excel 迁移到 64 位,现在用于提取 cookie 的宏不断崩溃。我知道 PtrSafe 声明,但这不再有效。 K google 试图找到它的正确声明,但似乎无法正确。也许有人可以指出 LongLong 或 LongPtr 需要在哪里使用?下面的代码是我的第 n 次尝试,没有运气:

'clear current cookies
Private Declare PtrSafe Function InternetSetOption Lib "wininet.dll" Alias "InternetSetOptionA" (ByVal hInternet As Long, ByVal lOption As Long, ByVal sBuffer As String, ByVal lBufferLength As Long) As LongPtr
'retrieve cookie
Private Declare PtrSafe Function InternetGetCookieEx Lib "wininet.dll" Alias "InternetGetCookieExA" (ByVal pchURL As String, ByVal pchCookieName As String, ByVal pchCookieData As String, ByRef pcchCookieData As Integer, ByVal dwFlags As Integer, ByVal lpReserved As Integer) As Boolean

Private Const INTERNET_OPTION_END_BROWSER_SESSION = 42
Private Const INTERNET_COOKIE_HTTPONLY As Integer = &H2000
Private Sub UserForm_Initialize()
    Call InternetSetOption(0, INTERNET_OPTION_END_BROWSER_SESSION, 0, 0)
    WebBrowser1.Silent = True
    'WebBrowser1.Navigate "salesforce.com"
    WebBrowser1.Navigate "salesforce.com"
End Sub

Private Sub WebBrowser1_DocumentComplete(ByVal pDisp As Object, URL As Variant)
    If URL Like "*/home.jsp*" Then
        Call InternetGetCookieEx(URL, "sid", sessionId, 256, INTERNET_COOKIE_HTTPONLY, vbNull)
        Unload Me
    End If
End Sub

【问题讨论】:

你的代码在哪里崩溃了?在InternetGetCookieEx? sessionId 在哪里声明,它是如何初始化的?我没有excel 64位,所以我什么都不能尝试,但是64位下的Ansi版本的API函数似乎不是正确的。 【参考方案1】:

答案是查看这些命令的 Microsoft 文档。当你调用这样的原生方法时,你会找到documentation is in C++,所以我们必须做一些翻译。

我们也可以看看Microsoft says about LongPtr是什么。

LongPtr 不是真正的数据类型,因为它转换为 Long in 32 位环境,或 64 位环境中的 LongLong。使用 LongPtr 支持编写可在 32 位和 64 位环境。将 LongPtr 用于指针和句柄。

在您的情况下,至少是句柄hInternet,但我也会覆盖缓冲区长度以避免溢出问题。我还将所有整数转换为长整数。

Private Declare PtrSafe Function InternetSetOption Lib "wininet.dll" Alias "InternetSetOptionA" (ByVal hInternet As LongPtr, ByVal lOption As Long, ByVal sBuffer As String, ByVal lBufferLength As LongPtr) As LongPtr

Private Declare PtrSafe Function InternetGetCookieEx Lib "wininet.dll" Alias "InternetGetCookieExA" (ByVal pchURL As String, ByVal pchCookieName As String, ByVal pchCookieData As String, ByRef pcchCookieData As Long, ByVal dwFlags As Long, ByVal lpReserved As LongPtr) As Boolean

编辑:我们还要声明 lpReserved As LongPtr,因为它以 lp 开头,这可能意味着长指针。

您必须注意的错误: 为避免原生代码中出现未处理的异常,请在调用原生方法之前检查此命令可以抛出的异常并加以防范。

返回码说明

ERROR_NO_MORE_ITEMS

指定的 URL 及其所有父级都没有 cookie。

ERROR_INSUFFICIENT_BUFFER

lpdwSize 传入的值不足以复制所有cookie 数据。 lpdwSize 中返回的值是缓冲区的大小 获取所有数据所必需的。

ERROR_INVALID_PARAMETER

一个或多个参数无效。

lpszUrl 参数为 NULL。

【讨论】:

您好,感谢您抽出宝贵时间回答,我尝试了您的声明,但它仍然崩溃。我现在有一种感觉,这可能不仅仅是与声明有关 崩溃在哪一行?是有错误,还是 Excel 刚刚关闭? 没有错误,excel只是关闭就这样。 是的,这是本机代码中未处理的异常。我添加了 get 方法可以抛出的异常列表。在调用方法之前确保它们不正确。 没有。如果您确保永远不会将错误的值传递给本机代码,那么它将起作用。最终,您正在编写依赖于 Internet Explorer 的代码。你应该完全停止这样做。 VBA 不是这项工作的最佳工具。如果您必须使用 VBA,至少停止重新发明***。使用库:github.com/VBA-tools/VBA-Web

以上是关于Wininet.dll 在提取 cookie 时崩溃 excel 64 位的主要内容,如果未能解决你的问题,请参考以下文章

使用 VS2010 在 C# 上出现 Wininet.dll 错误

使用 wininet.dll 的 FtpFindFirstFile 错误

webBroser获取cookie

WinForm WebBrowser 设置cookie

获取webbrowser的cookies

使用 wininet.dll api 从 FTP 站点搜索和检索文件名