【问题标题】:Use WinInet::InternetSetOption() always returns false and GetLastError() returns 12018使用 WinInet::InternetSetOption() 总是返回 false 并且 GetLastError() 返回 12018
【发布时间】:2014-01-07 12:29:11
【问题描述】:

我想让ie的IWebBrowser不需要选择证书,所以我用InternetSetOption()来做。代码是:

HCERTSTORE hMyStore = CertOpenSystemStore(0, _T("MY");
PCCERT_CONTEXT pDesiredCert = NULL;
pDesiredCert=CertFindCertificateInStore( 
    hMyStore, 
    X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
    CERT_FIND_SUBJECT_STR,
    L"cnstr",
    NULL);

if (InternetSetOption (NULL, INTERNET_OPTION_CLIENT_CERT_CONTEXT, 
        (LPVOID)pDesiredCert, sizeof(CERT_CONTEXT)) == FALSE) { 
    DOWRD i = GetLastError(); 
} 
...

我在“我的”商店获得证书。当我使用InternetSetOption()设置证书时,它返回false,错误代码是12018。我搜索了一些关于这个错误代码的信息:

“12018 ERROR_INTERNET_INCORRECT_HANDLE_TYPE 为该操作提供的句柄类型不正确。”

我想设置全局设置,所以我将第一个参数设置为NULL,函数InternetSetOption()中的第一个参数不能是NULL吗?我怎样才能正确设置选项?

【问题讨论】:

  • 为什么 c# 被标记?这是什么语言?如果 c++ 从标签中删除 c#
  • 对不起,因为我认为 C# 使用了一些 api。我已经删除了。
  • 您不能使用 NULL 句柄,并且 IE 不会公开它使用的 HINTERNET 句柄。当然,这意味着这种方法注定要失败。通过谷歌搜索“为 Internet Explorer 安装证书”取得成功。

标签: winapi visual-c++ wininet


【解决方案1】:

正如您已经说过的,您不能将NULL 用于INTERNET_OPTION_CLIENT_CERT_CONTEXT 选项。虽然,某些选项可以拥有NULL 值,例如INTERNET_OPTION_CONNECT_RETRIESINTERNET_OPTION_DATA_RECEIVE_TIMEOUT,但它不能。

Option Flags

您必须通过使用InternetOpen()InternetConnect() 来使用有效的HINTERNET。 下面的链接将指导您在“HINTERNET 句柄范围”部分找到有效的HINTERNET

Setting and Retrieving Internet Options

而且,您还必须检查 hMyStorepDesiredCert 值是否为 NULL

**编辑:**

使用IWebBrowser2 无法获取HINTERNET。它只是暴露了WebBrowser 控件的方法和属性。所以,你必须使用InternetConnect()

例如,需要具有身份验证的代理的客户端应用程序可能不需要在每次应用程序尝试访问 Internet 资源时设置代理用户名和密码。如果给定连接上的所有请求都由同一个代理处理,则在连接类型 HINTERNET 句柄上设置代理用户名和密码,即通过调用 InternetConnect 创建的句柄,将允许从该 HINTERNET 句柄派生的任何调用使用相同的代理用户名和密码。每次通过 HttpOpenRequest 创建 HINTERNET 句柄时设置代理用户名和密码将需要额外且不必要的开销。请注意,如果应用程序使用需要身份验证的代理,则应在每个新连接上设置代理凭据。

http://msdn.microsoft.com/en-us/library/windows/desktop/aa385384(v=vs.85).aspx

我还写了一些关于如何使用InternetConnect() 的有用参考链接。

C++ WinHTTP InternetReadFile not retrieving entire source

SSL with WinHTTP

【讨论】:

  • 谢谢,对我有帮助!我能拿到IWebBrowser2控件,这种情况怎么办?
  • @lvshuchengyin 我已经编辑了我的答案。我希望这会对你有所帮助。感谢您的评论。
  • InternetConnect() 不起作用。只有HttpOpenRequest的HINTERNET可以设置INTERNET_OPTION_CLIENT_CERT_CONTEXT,但是会影响IWebBrowser2。不过谢谢你的回答!
  • 我通过调用所有这些函数解决了这个问题: InternetOpen();互联网连接(); HttpOpenRequest(); InternetSetOption();InternetReadFile();感谢您的帮助!
【解决方案2】:

我相信应用的答案是正确的。虽然存在另一个问题,但它以类似的方式暴露出来。
如果常量INTERNET_OPTION_CLIENT_CERT_CONTEXT 定义不正确,您会得到错误“INCORRECT_HANDLE_TYPE”。在这种情况下,您只会传递错误的选项。 WinInet 中正确的值为84 (dec)

#define INTERNET_OPTION_CLIENT_CERT_CONTEXT 84

WinHttp中对应的常量应该是

#define WINHTTP_OPTION_CLIENT_CERT_CONTEXT 47

不要混合它们。小心点,祝您编码愉快!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-28
    • 1970-01-01
    • 2016-11-23
    • 1970-01-01
    • 2018-08-06
    相关资源
    最近更新 更多