我正在尝试使用以下函数处理ERROR_INTERNET_CLIENT_AUTH_CERT_NEEDED
错误:
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函数返回的Open Request Handle。第二个是GetLastError函数的结果。
在我的实现中,当GetLastError返回ERROR_INTERNET_CLIENT_AUTH_CERT_NEEDED
时,我会调用这个函数(例如):
CallInternetErrorDialog(OpenRequestHandle,ERROR_INTERNET_CLIENT_AUTH_CERT_NEEDED)
我期望的行为是系统的选择证书默认对话框,向用户显示一些证书:
但是,对InternetErrorDlg的内部调用只返回零(ERROR_SUCCESS),而不显示任何内容。
对于那些声称完整源代码的人来说,这是路线图。我不会把整个代码放在一起,因为它非常宽容。整个单元有超过800行代码:
步骤6调用我的函数,只需调用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_SUCCESS
,而不向用户显示任何内容,那么,ERROR_INTERNET_CLIENT_AUTH_CERT_NEEDED
错误的处理方式是什么?
步骤8中的错误是绝对自然的,因为在服务器发送ERROR_INTERNET_CLIENT_AUTH_CERT_NEEDED
之后,它等待下一次尝试(HttpSendRequest
)已经加载了有效证书。这证明InternetErrorDlg
函数尽管取得了成功,却没有做到它应该做的事情
请再次查看CallInternetErrorDialog以获取更多信息。