Delphi 为什么WinInet的InternetErrorDlg不能正确处理错误\u INTERNET\u CLIENT\u AUTH\u CERT\u所需?

Delphi 为什么WinInet的InternetErrorDlg不能正确处理错误\u INTERNET\u CLIENT\u AUTH\u CERT\u所需?,delphi,wininet,Delphi,Wininet,我正在尝试使用以下函数处理错误\u INTERNET\u CLIENT\u AUTH\u CERT\u所需错误: function CallInternetErrorDialog(AInetOpenRequest: HINTERNET; ALastError: DWORD): DWORD; var P: Pointer; begin Result := InternetErrorDlg(GetDesktopWindow() ,AIn

我正在尝试使用以下函数处理错误\u INTERNET\u CLIENT\u AUTH\u CERT\u所需错误:

function CallInternetErrorDialog(AInetOpenRequest: HINTERNET; ALastError: DWORD): DWORD;
var
  P: Pointer;
begin
  Result := InternetErrorDlg(GetDesktopWindow()
                            ,AInetOpenRequest
                            ,ALastError
                            ,FLAGS_ERROR_UI_FILTER_FOR_ERRORS or FLAGS_ERROR_UI_FLAGS_CHANGE_OPTIONS or FLAGS_ERROR_UI_FLAGS_GENERATE_DATA
                            ,P);

  // Only to check result (this is not important right now)
  case Result of
    ERROR_SUCCESS: OutputDebugString('ERROR_SUCCESS');
    ERROR_CANCELLED: OutputDebugString('ERROR_CANCELLED');
    ERROR_INTERNET_FORCE_RETRY: OutputDebugString('ERROR_INTERNET_FORCE_RETRY');
    ERROR_INVALID_HANDLE: OutputDebugString('ERROR_INVALID_HANDLE');
  end;

  if ALastError = ERROR_INTERNET_CLIENT_AUTH_CERT_NEEDED then
    Result := ERROR_INTERNET_FORCE_RETRY;
end;
这只是一个围绕InternetErrorDlg函数构建的辅助函数,它非常简单,有两个参数。第一个是打开请求句柄,由HttpOpenRequest函数返回。第二个是GetLastError函数的结果

在我的实现中,当GetLastError返回ERROR\u INTERNET\u CLIENT\u AUTH\u CERT\u所需时,我调用该函数,如下例所示:

CallInternetErrorDialog(OpenRequestHandle,ERROR_INTERNET_CLIENT_AUTH_CERT_NEEDED)
我预期的行为是系统的“选择证书默认”对话框显示给用户“选择某些证书”:

但是,对InternetErrorDlg的内部调用只会立即返回零错误,而不显示任何内容

对于那些声称拥有完整源代码的人,这里有路线图。我不会把整个代码放在这里,因为它非常扩展。整个单元有800多行代码:

InternetOpen句柄:=InternetOpen。。。; InternetConnectHandle:=InternetConnectionInternetOpenHandle,。。。; HttpOpenRequestHandle:=HttpOpenRequestInternetConnectHandle,。。。; HttpSendRequestResult:=HttpSendRequestHttpOpenRequestHandle,。。。; GetLastError=错误\u INTERNET\u客户端\u身份验证\u证书\u需要 CallInternetErrorDialogERROR\u INTERNET\u客户端\u身份验证\u证书\u所需,HttpOpenRequestHandle; 重复步骤4; GetLastError=错误\互联网\安全性\通道\错误 终止 步骤6调用my函数,该函数仅调用InternetErrorDlg,并使用以下已替换的参数:

InternetErrorDlg(GetDesktopWindow()
                ,HttpOpenRequestHandle
                ,ERROR_INTERNET_CLIENT_AUTH_CERT_NEEDED
                ,FLAGS_ERROR_UI_FILTER_FOR_ERRORS or FLAGS_ERROR_UI_FLAGS_CHANGE_OPTIONS or FLAGS_ERROR_UI_FLAGS_GENERATE_DATA
                ,P);
有了这些参数,InternetErrorDlg函数立即返回ERROR\u SUCCESS,而不向用户显示任何内容,那么,针对ERROR\u INTERNET\u CLIENT\u AUTH\u CERT\u所需的错误采取了什么样的策略呢

第八步的错误是完全自然的,因为在服务器发送所需的错误\u INTERNET\u CLIENT\u AUTH\u CERT\u之后,它会等待下一次尝试HttpSendRequest时已经加载了有效的证书。这证明了InternetErrorDlg函数,尽管您获得了成功的结果,但它并没有做它应该做的事情


有关详细信息,请再次查看CallInternetError对话框。

在假定InternetErrorDlg的返回值有效且有效之前,不检查它。在盲目使用ALastError值之前,您应该检查API调用并将结果与进行比较,以查看函数是否成功。@KenWhite感谢您的评论。让我解释一下。这个函数没有检查返回值,因为它是一个原型,但只是为了澄清问题,我用一个case语句检查了结果,并编辑了问题。现在我知道InternetErrorDlg正在返回ERROR\u SUCCESS。ALASERROR是一个输入参数,它确实是需要错误的INTERNET客户端身份验证证书,所以,如果我错了,请告诉我:InternetErrorDLG调用错误的INTERNET客户端身份验证证书不应该显示“选择证书”对话框?@Carlos,你看到了吗?@whosrdaddy是的,我看到了。这篇文章详细地展示了如何使用InternetErrorDlg来处理证书问题,我已经在这么做了。我这里的问题有点不同。我想知道为什么InternetErrorDlg函数在用于处理错误\u INTERNET\u CLIENT\u AUTH\u CERT\u所需错误时,不显示任何窗口以供用户选择某些证书安装的证书?。这篇文章只展示了一条快乐的道路,它没有在每种情况下都谈论InternetErrorDlg函数的行为。我添加了这个链接,因为它展示了一个完整的示例如何使用InternetErrorDlg,尽管在C语言中,更具体地说,调用对话框之前使用的代码似乎很有趣。如果你想从某人那里得到答案,你必须提交一份MVCE。。。