如何设置TIdHTTP使用IE代理配置?
它应该与XP / Vista / Win7兼容可靠.
它应该与XP / Vista / Win7兼容可靠.
解决方法
Indy不使用Internet Explorer的代理设置,因此您必须自己获取它,例如使用
InternetQueryOption
功能.
更新:
这是使用WinHTTP
的代码,应尝试从IE接收设置.如果它们可用并且自动检测代理设置或自动配置脚本URL选项被设置,则将执行代理检测.当IE设置不可用时,也会执行自动检测.
免责声明:
以下代码仅在最简单的情况下进行测试,当IE设置可用并且代理设置未被配置为自动检测(没有环境)时.还请注意,本单元中的一些功能,结构和常数是额外的.
unit Unit1; interface uses Windows,Messages,SysUtils,Variants,Classes,Graphics,Controls,Forms,Dialogs,StdCtrls; type TForm1 = class(TForm) Button1: TButton; procedure FormCreate(Sender: TObject); procedure Button1Click(Sender: TObject); private { Private declarations } public { Public declarations } end; type HINTERNET = Pointer; {$EXTERNALSYM HINTERNET} INTERNET_PORT = Word; {$EXTERNALSYM INTERNET_PORT} PWinHTTPProxyInfo = ^TWinHTTPProxyInfo; WINHTTP_PROXY_INFO = record dwAccessType: DWORD; lpszProxy: LPWSTR; lpszProxyBypass: LPWSTR; end; {$EXTERNALSYM WINHTTP_PROXY_INFO} TWinHTTPProxyInfo = WINHTTP_PROXY_INFO; LPWINHTTP_PROXY_INFO = PWinHTTPProxyInfo; {$EXTERNALSYM LPWINHTTP_PROXY_INFO} PWinHTTPAutoProxyOptions = ^TWinHTTPAutoProxyOptions; WINHTTP_AUTOPROXY_OPTIONS = record dwFlags: DWORD; dwAutoDetectFlags: DWORD; lpszAutoConfigUrl: LPCWSTR; lpvReserved: Pointer; dwReserved: DWORD; fAutologonIfChallenged: BOOL; end; {$EXTERNALSYM WINHTTP_AUTOPROXY_OPTIONS} TWinHTTPAutoProxyOptions = WINHTTP_AUTOPROXY_OPTIONS; LPWINHTTP_AUTOPROXY_OPTIONS = PWinHTTPAutoProxyOptions; {$EXTERNALSYM LPWINHTTP_AUTOPROXY_OPTIONS} PWinHTTPCurrentUserIEProxyConfig = ^TWinHTTPCurrentUserIEProxyConfig; WINHTTP_CURRENT_USER_IE_PROXY_CONFIG = record fAutoDetect: BOOL; lpszAutoConfigUrl: LPWSTR; lpszProxy: LPWSTR; lpszProxyBypass: LPWSTR; end; {$EXTERNALSYM WINHTTP_CURRENT_USER_IE_PROXY_CONFIG} TWinHTTPCurrentUserIEProxyConfig = WINHTTP_CURRENT_USER_IE_PROXY_CONFIG; LPWINHTTP_CURRENT_USER_IE_PROXY_CONFIG = PWinHTTPCurrentUserIEProxyConfig; {$EXTERNALSYM LPWINHTTP_CURRENT_USER_IE_PROXY_CONFIG} function WinHttpOpen(pwszUserAgent: LPCWSTR; dwAccessType: DWORD; pwszProxyName,pwszProxyBypass: LPCWSTR; dwFlags: DWORD): HINTERNET; stdcall; external 'winhttp.dll' name 'WinHttpOpen'; {$EXTERNALSYM WinHttpOpen} function WinHttpConnect(hSession: HINTERNET; pswzServerName: LPCWSTR; nServerPort: INTERNET_PORT; dwReserved: DWORD): HINTERNET; stdcall; external 'winhttp.dll' name 'WinHttpConnect'; {$EXTERNALSYM WinHttpConnect} function WinHttpOpenRequest(hConnect: HINTERNET; pwszVerb: LPCWSTR; pwszObjectName: LPCWSTR; pwszVersion: LPCWSTR; pwszReferer: LPCWSTR; ppwszAcceptTypes: PLPWSTR; dwFlags: DWORD): HINTERNET; stdcall; external 'winhttp.dll' name 'WinHttpOpenRequest'; {$EXTERNALSYM WinHttpOpenRequest} function WinHttpQueryOption(hInet: HINTERNET; dwOption: DWORD; lpBuffer: Pointer; var lpdwBufferLength: DWORD): BOOL; stdcall; external 'winhttp.dll' name 'WinHttpQueryOption'; {$EXTERNALSYM WinHttpQueryOption} function WinHttpGetProxyForUrl(hSession: HINTERNET; lpcwszUrl: LPCWSTR; pAutoProxyOptions: LPWINHTTP_AUTOPROXY_OPTIONS; var pProxyInfo: WINHTTP_PROXY_INFO): BOOL; stdcall; external 'winhttp.dll' name 'WinHttpGetProxyForUrl'; {$EXTERNALSYM WinHttpGetProxyForUrl} function WinHttpGetIEProxyConfigForCurrentUser( var pProxyInfo: WINHTTP_CURRENT_USER_IE_PROXY_CONFIG): BOOL; stdcall; external 'winhttp.dll' name 'WinHttpGetIEProxyConfigForCurrentUser'; {$EXTERNALSYM WinHttpGetIEProxyConfigForCurrentUser} function WinHttpCloseHandle(hInternet: HINTERNET): BOOL; stdcall; external 'winhttp.dll' name 'WinHttpCloseHandle'; {$EXTERNALSYM WinHttpCloseHandle} const WINHTTP_NO_REFERER = nil; {$EXTERNALSYM WINHTTP_NO_REFERER} WINHTTP_NO_PROXY_NAME = nil; {$EXTERNALSYM WINHTTP_NO_PROXY_NAME} WINHTTP_NO_PROXY_BYPASS = nil; {$EXTERNALSYM WINHTTP_NO_PROXY_BYPASS} WINHTTP_DEFAULT_ACCEPT_TYPES = nil; {$EXTERNALSYM WINHTTP_DEFAULT_ACCEPT_TYPES} WINHTTP_ACCESS_TYPE_DEFAULT_PROXY = 0; {$EXTERNALSYM WINHTTP_ACCESS_TYPE_DEFAULT_PROXY} WINHTTP_ACCESS_TYPE_NO_PROXY = 1; {$EXTERNALSYM WINHTTP_ACCESS_TYPE_NO_PROXY} WINHTTP_OPTION_PROXY = 38; {$EXTERNALSYM WINHTTP_OPTION_PROXY} WINHTTP_OPTION_PROXY_USERNAME = $1002; {$EXTERNALSYM WINHTTP_OPTION_PROXY_USERNAME} WINHTTP_OPTION_PROXY_PASSWORD = $1003; {$EXTERNALSYM WINHTTP_OPTION_PROXY_PASSWORD} WINHTTP_AUTOPROXY_AUTO_DETECT = $00000001; {$EXTERNALSYM WINHTTP_AUTOPROXY_AUTO_DETECT} WINHTTP_AUTOPROXY_CONFIG_URL = $00000002; {$EXTERNALSYM WINHTTP_AUTOPROXY_CONFIG_URL} WINHTTP_AUTO_DETECT_TYPE_DHCP = $00000001; {$EXTERNALSYM WINHTTP_AUTO_DETECT_TYPE_DHCP} WINHTTP_AUTO_DETECT_TYPE_DNS_A = $00000002; {$EXTERNALSYM WINHTTP_AUTO_DETECT_TYPE_DNS_A} WINHTTP_FLAG_BYPASS_PROXY_CACHE = $00000100; {$EXTERNALSYM WINHTTP_FLAG_BYPASS_PROXY_CACHE} WINHTTP_FLAG_REFRESH = WINHTTP_FLAG_BYPASS_PROXY_CACHE; {$EXTERNALSYM WINHTTP_FLAG_REFRESH} var Form1: TForm1; implementation {$R *.dfm} type TProxyInfo = record ProxyURL: WideString; ProxyBypass: WideString; ProxyAutoDetected: Boolean; end; function GetProxyInfo(const AURL: WideString; var AProxyInfo: TProxyInfo): DWORD; var Session: HINTERNET; AutoDetectProxy: Boolean; WinHttpProxyInfo: TWinHTTPProxyInfo; AutoProxyOptions: TWinHTTPAutoProxyOptions; IEProxyConfig: TWinHTTPCurrentUserIEProxyConfig; begin // initialize the result Result := 0; // initialize auto-detection to off AutoDetectProxy := False; // initialize the result structure AProxyInfo.ProxyURL := ''; AProxyInfo.ProxyBypass := ''; AProxyInfo.ProxyAutoDetected := False; // initialize the auto-proxy options FillChar(AutoProxyOptions,SizeOf(AutoProxyOptions),0); // check if the Internet Explorer's proxy configuration is // available and if so,check its settings for auto-detect // proxy settings and auto-config script URL options if WinHttpGetIEProxyConfigForCurrentUser(IEProxyConfig) then begin // if the Internet Explorer is configured to auto-detect // proxy settings then we try to detect them later on if IEProxyConfig.fAutoDetect then begin AutoProxyOptions.dwFlags := WINHTTP_AUTOPROXY_AUTO_DETECT; AutoProxyOptions.dwAutoDetectFlags := WINHTTP_AUTO_DETECT_TYPE_DHCP or WINHTTP_AUTO_DETECT_TYPE_DNS_A; AutoDetectProxy := True; end; // if the Internet Explorer is configured to use the proxy // auto-config script then we try to use it if IEProxyConfig.lpszAutoConfigURL <> '' then begin AutoProxyOptions.dwFlags := AutoProxyOptions.dwFlags or WINHTTP_AUTOPROXY_CONFIG_URL; AutoProxyOptions.lpszAutoConfigUrl := IEProxyConfig.lpszAutoConfigUrl; AutoDetectProxy := True; end; // if IE don't have auto-detect or auto-config set,we are // done here and we can fill the AProxyInfo with the IE settings if not AutoDetectProxy then begin AProxyInfo.ProxyURL := IEProxyConfig.lpszProxy; AProxyInfo.ProxyBypass := IEProxyConfig.lpszProxyBypass; AProxyInfo.ProxyAutoDetected := False; end; end else begin // if the Internet Explorer's proxy configuration is not // available,then try to auto-detect it AutoProxyOptions.dwFlags := WINHTTP_AUTOPROXY_AUTO_DETECT; AutoProxyOptions.dwAutoDetectFlags := WINHTTP_AUTO_DETECT_TYPE_DHCP or WINHTTP_AUTO_DETECT_TYPE_DNS_A; AutoDetectProxy := True; end; // if the IE proxy settings are not available or IE has // configured auto-config script or auto-detect proxy settings if AutoDetectProxy then begin // create a temporary WinHttp session to allow the WinHTTP // auto-detect proxy settings if possible Session := WinHttpOpen(nil,WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,WINHTTP_NO_PROXY_NAME,WINHTTP_NO_PROXY_BYPASS,0); // if the WinHttp session has been created then try to // get the proxy data for the specified URL else we assign // the last error code to the function result if Assigned(Session) then try // get the proxy data for the specified URL with the // auto-proxy options specified,if succeed then we can // fill the AProxyInfo with the retrieved settings else // we assign the last error code to the function result if WinHttpGetProxyForUrl(Session,LPCWSTR(AURL),@AutoProxyOptions,WinHttpProxyInfo) then begin AProxyInfo.ProxyURL := WinHttpProxyInfo.lpszProxy; AProxyInfo.ProxyBypass := WinHttpProxyInfo.lpszProxyBypass; AProxyInfo.ProxyAutoDetected := True; end else Result := GetLastError; finally WinHttpCloseHandle(Session); end else Result := GetLastError; end; end; procedure TForm1.Button1Click(Sender: TObject); var Result: DWORD; ProxyInfo: TProxyInfo; begin Result := GetProxyInfo('http://www.example.com',ProxyInfo); case Result of 0: ShowMessage( 'Proxy URL: ' + ProxyInfo.ProxyURL + sLineBreak + 'Proxy bypass: ' + ProxyInfo.ProxyBypass + sLineBreak + 'Proxy autodetected: ' + BoolToStr(ProxyInfo.ProxyAutoDetected,True)); 12166: ShowMessage('Error in proxy auto-config script code'); 12167: ShowMessage('Unable to download proxy auto-config script'); 12180: ShowMessage('WPAD detection Failed'); else ShowMessage('Last error: ' + IntToStr(Result)); end; end; procedure TForm1.FormCreate(Sender: TObject); begin ReportMemoryLeaksOnShutdown := True; end; end.
以下是如何使用获取的代理设置设置TIdHTTP的示例(实际上您只需解析获取的代理URL并将其传递到ProxyServer
和ProxyPort
属性):
uses IdGlobal; procedure TForm1.Button1Click(Sender: TObject); var S: string; Result: DWORD; ProxyInfo: TProxyInfo; begin Result := GetProxyInfo('http://www.example.com',ProxyInfo); if Result <> 0 then IdHTTP1.ProxyParams.Clear else begin S := ProxyInfo.ProxyURL; IdHTTP1.ProxyParams.ProxyServer := Fetch(S,':'); IdHTTP1.ProxyParams.ProxyPort := StrToInt(S); end; end;