2012-01-22 30 views

Trả lời

23

Indy không sử dụng cài đặt proxy của Internet Explorer và vì vậy bạn phải tự mình thực hiện cài đặt proxy, ví dụ bằng cách sử dụng chức năng InternetQueryOption.

Cập nhật:

Đây là đoạn mã sử dụng WinHTTP mà nên cố gắng để nhận các thiết lập từ trình duyệt IE. Nếu chúng khả dụng và tự động phát hiện cài đặt proxy hoặc URL tập lệnh tự động định cấu hình tùy chọn được đặt, khi đó việc phát hiện proxy sẽ được thực hiện. Tự động phát hiện cũng sẽ được thực hiện khi cài đặt IE không khả dụng.

Disclaimer:

Các mã sau đây đã được thử nghiệm chỉ dành cho các trường hợp đơn giản nhất, khi các thiết lập trình duyệt IE có sẵn và các cài đặt proxy không được cấu hình để được phát hiện tự động (không có môi trường). Cũng xin lưu ý rằng một số chức năng, cấu trúc và hằng số được bổ sung trong đơn vị này.

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. 

Để có mã thay thế Delphi bạn có thể kiểm tra ví dụ: this tip.

Dưới đây là một ví dụ về làm thế nào để thiết lập một TIdHTTP với cài đặt proxy thu được (trên thực tế bạn chỉ cần phân tích cú pháp URL proxy đạt được và vượt qua nó để ProxyServerProxyPort tài sản):

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; 
+4

+1 đã thêm liên kết vào một số mã mẫu delphi ... – Yahia

+0

Bạn có ý nghĩa gì với mã delphi "cũ"? Nó cũng sẽ hỗ trợ [Giao thức Autodiscovery Web Proxy] (http://en.wikipedia.org/wiki/Web_Proxy_Autodiscovery_Protocol)? – ZigiZ

+0

@ zigi70, ghi chú có liên kết được thêm bởi Yahia có nghĩa là hầu hết các ví dụ mã là 7 tuổi. Cho câu hỏi _if WPAD sẽ được hỗ trợ_, có nó sẽ, nhưng bạn có thể phải đối mặt với các vấn đề như ['this'] (http://stackoverflow.com/a/5138232/960757) ví dụ. Hàm 'InternetQueryOption' được sử dụng để định vị kịch bản cấu hình proxy gần đây nhất được phát hiện bởi Internet Explorer, vì vậy nếu bạn đã bật' WPAD' và bạn đã được kết nối, thì có thể bạn sẽ nhận được các cài đặt gần đây nhất được phát hiện tự động trước đó. – TLama

9

Bạn có thể lấy nó còn thông qua Windows Registry dưới dạng:

var 
    Reg: TRegistry; 
begin 
    Reg := TRegistry.Create; 
    Reg.RootKey := HKEY_CURRENT_USER; 
    Reg.OpenKey('Software\Microsoft\Windows\CurrentVersion\Internet Settings',false); 
    Caption :=Reg.ReadString('ProxyServer'); 
    Reg.Free; 
end; 
Các vấn đề liên quan