Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I set each TWebBrowser to use an independent proxy?

I have found all kind of examples about how to make TWebBrowser use a proxy (like 202.8.128.5:8080). However all those examples are changing the proxy globally for all running instances of TWebBrowser. I have two instances. How do I set a different proxy for each browser?

like image 273
Beno Avatar asked Feb 25 '15 11:02

Beno


1 Answers

This can be achieved using the following code (public code, not mine):

{$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;
  • Drop two TWebBrowser components on your form and two TButton
  • TWebBrowser components will have the default names WebBrowser1 and WebBrowser2
  • The twoTButton will have the default names Button1 and Button2
  • Add WinInet to your uses clause

Call the above function in Button1

Code for Button1 OnClick event:

procedure TForm1.Button1Click(Sender: TObject);
begin
SetProxy('ip:port');
WebBrowser1.Navigate('www.whatismyipaddress.com');
end;

Code for Button2 OnClick event:

procedure TForm1.Button2Click(Sender: TObject);
begin
SetProxy('ip:port');
WebBrowser2.Navigate('www.whatismyipaddress.com');
end;

And here is how it looks:

enter image description here

On the left is WebBrowser1 with a proxy and on the right is WebBrowser2 with a different proxy - both browsers are in the same application and apparently they worked. I've also visited the address from my regular browser (Chrome) while the application was running and it indeed showed up as using my original connection.

So, it works. The WebBrowser components are using their assigned proxy's while the browser on my pc remains unaffected (isn't using either of the proxy's)

Tested this using Rad Studio 10.2 Tokyo just now. Good luck :)

UPDATE

As highlighted in the comments, a way to set the proxy that will be used to navigate, without setting it at design time or in the button you use to Navigate is by using a TStringList and loading it from a file (.txt, for example). This can be used in the TWebBrowser OnBeforeNavigate2 event.

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;

Create a .txt file named proxylist in your application folder and write the proxy there.

Now you'll have a proxy set for your TWebBrowser before you begin to navigate. Either way, I'm sure there a lot of ways to expand this so use your imagination.

like image 108
t1f Avatar answered Oct 25 '22 18:10

t1f