Ho trovato tutti i tipi di examples su come far utilizzare a TWebBrowser un proxy (come 202.8.128.5:8080). Tuttavia, tutti questi esempi stanno cambiando il proxy a livello globale per tutte le istanze in esecuzione di TWebBrowser. Ho due istanze. Come posso impostare un proxy diverso per ciascun browser?Come si imposta ciascun TWebBrowser per utilizzare un proxy indipendente?
risposta
questo può essere realizzato utilizzando il seguente codice (codice pubblico, non mia):
{$DEFINE DELPHI2009_UP}
function SetProxy(Server: String): Boolean;
// Server z.B. '127.0.0.1:8080' oder ''
type
INTERNET_PER_CONN_OPTION = record
dwOption: DWORD;
Value: record case Integer of 1: (dwValue: DWORD);
2: (pszValue: {$IFDEF DELPHI2009_UP}PWideChar{$ELSE}PAnsiChar{$ENDIF});
3: (ftValue: TFileTime);
end;
end;
LPINTERNET_PER_CONN_OPTION = ^INTERNET_PER_CONN_OPTION;
INTERNET_PER_CONN_OPTION_LIST = record dwSize: DWORD;
pszConnection:
LPTSTR;
dwOptionCount:
DWORD;
dwOptionError:
DWORD;
pOptions:
LPINTERNET_PER_CONN_OPTION;
end;
LPINTERNET_PER_CONN_OPTION_LIST = ^INTERNET_PER_CONN_OPTION_LIST;
const
INTERNET_PER_CONN_FLAGS = 1;
INTERNET_PER_CONN_PROXY_SERVER = 2;
INTERNET_PER_CONN_PROXY_BYPASS = 3;
INTERNET_PER_CONN_AUTOCONFIG_URL = 4;
INTERNET_PER_CONN_AUTODISCOVERY_FLAGS = 5;
PROXY_TYPE_DIRECT = $00000001;
PROXY_TYPE_PROXY = $00000002;
PROXY_TYPE_AUTO_PROXY_URL = $00000004;
PROXY_TYPE_AUTO_DETECT = $00000008;
INTERNET_OPTION_REFRESH = 37;
INTERNET_OPTION_PER_CONNECTION_OPTION = 75;
INTERNET_OPTION_SETTINGS_CHANGED = 39;
var
OptionsList: INTERNET_PER_CONN_OPTION_LIST;
BufSize: DWORD;
HInternet: Pointer;
Agent: String;
begin
Result := False;
BufSize := SizeOf(OptionsList);
OptionsList.dwSize := BufSize;
OptionsList.pszConnection := nil; // nil -> LAN, sonst Verbindungsname
OptionsList.dwOptionCount := 3; // 3 Optionen werden gesetzt
OptionsList.pOptions := AllocMem(3 * SizeOf(INTERNET_PER_CONN_OPTION));
try
if not Assigned(OptionsList.pOptions) then
EXIT;
OptionsList.pOptions^.dwOption := INTERNET_PER_CONN_FLAGS;
OptionsList.pOptions^.Value.dwValue := PROXY_TYPE_DIRECT or
PROXY_TYPE_PROXY;
inc(OptionsList.pOptions);
OptionsList.pOptions^.dwOption := INTERNET_PER_CONN_PROXY_SERVER;
OptionsList.pOptions^.Value.pszValue := PChar(Server);
inc(OptionsList.pOptions);
OptionsList.pOptions^.dwOption := INTERNET_PER_CONN_PROXY_BYPASS;
OptionsList.pOptions^.Value.pszValue := 'local';
dec(OptionsList.pOptions, 2);
Agent := ExtractFileName(Application.ExeName);
HInternet := InternetOpen
({$IFDEF DELPHI2009_UP}PWideChar{$ELSE}PAnsiChar{$ENDIF}
(Agent), INTERNET_OPEN_TYPE_DIRECT, nil, nil, 0);
try // Optionen setzen
Result := InternetSetOption(HInternet,
INTERNET_OPTION_PER_CONNECTION_OPTION, @OptionsList, BufSize);
InternetSetOption(HInternet, INTERNET_OPTION_REFRESH, nil, 0);
finally
InternetCloseHandle(HInternet);
end;
finally
FreeMem(OptionsList.pOptions); // Speicher freigeben
end;
end;
- goccia due
TWebBrowser
componenti sul modulo e dueTButton
TWebBrowser
componenti avranno i nomi predefiniti WebBrowser1 e WebBrowser2- I due
TButton
avranno i nomi predefiniti Button1 e Button2 - Aggiungi
WinInet
aluses
clausola
Chiamare la funzione di cui sopra in Button1
Codice in Button1
OnClick
evento:
procedure TForm1.Button1Click(Sender: TObject);
begin
SetProxy('ip:port');
WebBrowser1.Navigate('www.whatismyipaddress.com');
end;
Codice in Button2
OnClick
evento:
procedure TForm1.Button2Click(Sender: TObject);
begin
SetProxy('ip:port');
WebBrowser2.Navigate('www.whatismyipaddress.com');
end;
Ed ecco come appare:
a sinistra è WebBrowser1 con un proxy e sulla destra è WebBrowser2 con un proxy diverso - Entrambi i browser sono nella stessa applicazione e apparentemente hanno funzionato. Ho anche visitato l'indirizzo dal mio browser normale (Chrome) mentre l'applicazione era in esecuzione e in effetti si presentava come se usassi la mia connessione originale.
Quindi, funziona. I componenti WebBrowser utilizzano i proxy assegnati mentre il browser sul mio pc rimane inalterato (non utilizza nessuno dei due proxy)
Testato utilizzando Rad Studio 10.2 Tokyo proprio ora. Buona fortuna :)
UPDATE
Come evidenziato nei commenti, un modo per impostare il proxy che verrà utilizzato per navigare, senza impostarla in fase di progettazione o nel pulsante si utilizza per Navigate
è utilizzando uno TStringList
e caricandolo da un file (.txt, ad esempio). Può essere utilizzato nell'evento TWebBrowser
OnBeforeNavigate2
.
procedure TForm1.WebBrowser1BeforeNavigate2(ASender: TObject; const pDisp: IDispatch; var URL, Flags, TargetFrameName, PostData, Headers: OleVariant; var Cancel: WordBool);
var
proxylist: TStringList;
begin
proxylist:= TStringList.Create;
proxylist.LoadFromFile('proxylist.txt');
SetProxy(proxylist.Strings[0]); //adds the proxy from the 1st line in the txt
proxylist.Free;
end;
Creare un file .txt denominato proxylist nella cartella dell'applicazione e scrivere il proxy lì.
Ora avrai un set proxy per il tuo TWebBrowser
prima di iniziare a navigare. Ad ogni modo, sono sicuro che ci sono molti modi per espandere questo, quindi usa la tua immaginazione.
Cosa succede se aggiungi un terzo pulsante che chiama 'Navigate()' su entrambi i controlli del browser senza prima impostare il proxy? Non ho provato ma presumo che ciò provi che le due istanze del browser non utilizzano in realtà proxy indipendenti ma solo l'ultima impostata. – mghie
@mghie La domanda era: come impostare un proxy diverso per ciascun 'TWebBrowser' senza modificare le impostazioni globali sul sistema o l'un l'altro. È possibile impostare il proxy nell'evento 'TWebBrowser'' OnBeforeNavigate2', in fase di progettazione o utilizzando una TStringList e caricando un proxy da un elenco .txt/.ini nella cartella del programma, indicando quale linea caricare, ciclicandoli e così via. L'ho appena testato e posso confermare che anche questo approccio funziona e ti evita il problema, puoi navigare liberamente una volta impostato utilizzando l'evento. – Petzy
https://msdn.microsoft.com/en-us/library/windows/desktop/aa385328.aspx#INTERNET_OPTION_PER_CONNECTION_OPTION –
Queste opzioni si applicano alle API WinInet, che 'TWebBrowser' non usa. Utilizza invece l'interfaccia 'IWebBrowser2'. Anche se 'IWebBrowser2' è un wrapper per Internet Explorer, che utilizza WinInet internamente, non è possibile applicare le opzioni WinInet peristanza a' IWebBrowser2'. Possono essere utilizzati solo quando l'API WinInet viene utilizzata direttamente. –
Peccato. Molte grazie comunque. – Beno