2012-01-22 4 views

risposta

23

Indy non utilizza le impostazioni proxy di Internet Explorer e quindi è necessario farlo da soli, ad esempio utilizzando la funzione InternetQueryOption.

Aggiornamento:

Ecco il codice utilizzando WinHTTP che dovrebbe cercare di ricevere le impostazioni da Internet Explorer. Se sono disponibili e le impostazioni del proxy di rilevamento automatico o o sono impostate automaticamente all'URL dello script di configurazione, verrà eseguito il rilevamento del proxy. Il rilevamento automatico verrà eseguito anche quando le impostazioni IE non sono disponibili.

responsabilità:

Il seguente codice è stato testato solo per il caso più semplice, quando le impostazioni di IE sono disponibili e le impostazioni proxy non sono configurati per essere rilevato automaticamente (non hanno il ambiente). Si noti inoltre che alcune funzioni, strutture e costante sono aggiuntive in questa unità.

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. 

Per un codice Delphi alternativo è possibile controllare ad es. this tip.

Ecco un esempio di come impostare un TIdHTTP con le impostazioni del proxy ottenuti (in realtà è sufficiente analizzare l'URL del proxy ottenuto e passarlo alle proprietà ProxyServer e 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; 
+4

+1 aggiunto un link al codice Delphi campione ... – Yahia

+0

Che cosa si intende per codice di Delphi "vecchio"? Supporterà anche [Web Proxy Autodiscovery Protocol] (http://en.wikipedia.org/wiki/Web_Proxy_Autodiscovery_Protocol)? – ZigiZ

+0

@ zigi70, la nota con il collegamento aggiunto da Yahia significa molto probabilmente che l'esempio di codice ha 7 anni. Alla domanda _se WPAD sarà supportato_, sì lo farà, ma potresti affrontare problemi come ['this'] (http://stackoverflow.com/a/5138232/960757) per esempio. La funzione 'InternetQueryOption' è usata per localizzare lo script di configurazione del proxy più recentemente rilevato da Internet Explorer, quindi se hai il' WPAD' abilitato e sei stato connesso, probabilmente otterrai le impostazioni più recenti rilevate automaticamente in precedenza. – TLama

9

si può ottenere anche attraverso Registro di sistema di Windows come:

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;