2007/01/23

via Proxy.

今日はフランスはパリ13区にお住まいの、Rachel Roblin(仮名)さんからの質問にお答えしたいと思います。

CSharpでWebBrowserControlを使った簡易なインターネットブラウザを作ってるんだけど、Proxyサーバーの設定方法がわからないんだ。

もちろん、Internet Explorerの設定を共有しているのは知ってるよ。だけど、FireFoxとIEの関係みたないに独立した設定がしたいんだ。

僕の作ったBrowserの為にIEの設定まで変更されてしまうのはどうかなと思うし。

不思議な事にControlのプロパティにもメゾッドにもそれらしき項目は無いんだよ。

何か方法はない?

こんなFrenchな人のFrankな質問メールですが、ちょっと調べてみましたが確かに該当するPropertyもMethodも無いんですね。

IEのコンポーネントになんて長いこと使ってなかったのですが、Urlmon.dllで確かって記憶が残ってました。実際に調べてみるとUrlMkSetSessionOptionとかで自プロセスで扱うコンポーネントのProxy設定とかが出来るようです。

C#はそれなりに便利にAPIを呼ぶ仕掛けが用意されているのですが、構造体とか入ってくるとちょっと難易度は上がります。というかかなり変態なコードになるので、通常のBusiness Logicなんか書いてあるファイルには書きたくない感じになります。

とりあえず、こんなコードを書いてみました。



using System;
using System.Runtime.InteropServices;

class urlmon
{
[DllImport("urlmon.dll", CharSet = CharSet.Ansi)]
private static extern int UrlMkSetSessionOption(
int dwOption, IntPtr pIpi, int nLength, int dwReserved);

public enum InternetOpenType: int{
INTERNET_OPEN_TYPE_PRECONFIG = 0 // use registry configuration
,INTERNET_OPEN_TYPE_DIRECT = 1 // direct to net
,INTERNET_OPEN_TYPE_PROXY = 3 // via named proxy
,INTERNET_OPEN_TYPE_PRECONFIG_WITH_NO_AUTOPROXY = 4 // prevent using java/script/INS
}

private struct INTERNET_PROXY_INFO
{
public InternetOpenType dwAccessType;
public IntPtr proxy;
public IntPtr proxyBypass;
};

//
public static int InternetOptionProxy(InternetOpenType nOpenType)
{
return InternetOptionProxy(nOpenType,"","");
}

//
public static int InternetOptionProxy(InternetOpenType nOpenType
, string proxy, string proxyBypass)
{
const int INTERNET_OPTION_PROXY = 38;

INTERNET_PROXY_INFO ipi;
ipi.dwAccessType = nOpenType;
ipi.proxy = Marshal.StringToHGlobalAnsi(proxy);
ipi.proxyBypass = Marshal.StringToHGlobalAnsi(proxyBypass);

IntPtr pStruct = Marshal.AllocCoTaskMem(Marshal.SizeOf(ipi));
Marshal.StructureToPtr(ipi, pStruct, true);

return UrlMkSetSessionOption(INTERNET_OPTION_PROXY, pStruct, Marshal.SizeOf(ipi), 0);
}
}


クラス名とかはurlmon.dllを呼び出すコードを誰かが書き足してくれればという願いを込めて付けましたりしてますし、本来はPropertyとしてGet,Setを実装すべきだろうとは思いますが、自分で使わないのと説明がメインのコードなんで。

Function自体はstaticになっているので、以下のような感じでWebBrowserControlの貼ってあるFormのLoadイベントとかで呼び出せばいいんではないでしょうか。設定変更があるならば、その都度呼んでも良いと思いますし。

urlmon.InternetOptionProxy(urlmon.InternetOpenType.INTERNET_OPEN_TYPE_PROXY, "localhost:8080", "");

というわけでRachel 、また旨いワイン奢ってね。

関連のありそうな記事

0 コメント: