Setting IE proxy setting programmatically

E

Epetruk

Hi,

I wrote this class to try to set the proxy settings in Internet Explorer
programmatically. The class uses the API functions in wininet.dll; however,
there's a horrible crash when I call InternetSetOption the first time. Can
anyone tell me what I'm doing wrong?

Epetruk



public class IESettingsApp
{
public enum IESettingOptions
{
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,
INTERNET_OPTION_REFRESH = 37,
INTERNET_OPTION_PER_CONNECTION_OPTION = 75,
INTERNET_OPTION_SETTINGS_CHANGED = 39,
PROXY_TYPE_PROXY = 2,
PROXY_TYPE_DIRECT = 1,
};

[StructLayout(LayoutKind.Sequential)]
struct FILETIME
{
public UInt32 dwLowDate;
public UInt32 dwHighDate;
};

//special way of handling unions - 2nd, 3rd and 4th fields begin at
same loc
[StructLayout(LayoutKind.Explicit, Size = 12)]
struct INTERNET_PER_CONN_OPTION
{
[FieldOffset(0)]
public UInt32 dwOption;
[FieldOffset(4)]
public UInt32 dwValue;
[FieldOffset(4)]
public IntPtr pszValue;
[FieldOffset(4)]
public FILETIME ftValue;

};

[StructLayout(LayoutKind.Sequential)]
struct INTERNET_PER_CONN_OPTION_LIST
{
public UInt32 dwSize;
public String pszConnection;
public UInt32 dwOptionCount;
public UInt32 dwOptionError;
public IntPtr pOptions;
};

[DllImport("wininet.dll", SetLastError = true, CharSet =
CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
private extern static bool InternetSetOption(IntPtr hInternet,
UInt32 dwOption, INTERNET_PER_CONN_OPTION_LIST lpBuffer, UInt32
dwBufferLength);

public static void SetIEProxySettings(String strProxyServer, String
strProxyBypassAddresses)
{
const int numIpcos = 3;

//create the INTERNET_PER_CONN_OPTION_LIST, and set its size
INTERNET_PER_CONN_OPTION_LIST ipcoList = new
INTERNET_PER_CONN_OPTION_LIST();
UInt32 ipcoListSize = (UInt32)Marshal.SizeOf(ipcoList);
ipcoList.dwSize = ipcoListSize;
ipcoList.pszConnection = null;
ipcoList.dwOptionCount = numIpcos;

INTERNET_PER_CONN_OPTION[] ipcoArr = new
INTERNET_PER_CONN_OPTION[numIpcos];
int ipcoSize = Marshal.SizeOf(ipcoArr[0]);

//use proxy server
ipcoArr[0].dwOption =
(UInt32)(IESettingOptions.INTERNET_PER_CONN_FLAGS);
ipcoArr[0].dwValue =
(UInt32)IESettingOptions.INTERNET_PER_CONN_PROXY_SERVER;

//use *this* proxy server
ipcoArr[1].dwOption =
(UInt32)IESettingOptions.INTERNET_PER_CONN_PROXY_SERVER;
ipcoArr[1].pszValue =
Marshal.StringToHGlobalAnsi(strProxyServer);

bypass these addresses for the proxy
ipcoArr[2].dwOption =
(UInt32)IESettingOptions.INTERNET_PER_CONN_PROXY_BYPASS;
ipcoArr[2].pszValue =
Marshal.StringToHGlobalAnsi(strProxyBypassAddresses);

//now create a buffer that will hold all the
INTERNET_PER_CONN_OPTIONS we've created
byte[] ipcoBuf = new byte[ipcoSize * numIpcos];

for (int i = 0; i < numIpcos; i++)
{
//copy the dwOption first
BitConverter.GetBytes(ipcoArr.dwOption).CopyTo(ipcoBuf, i
* ipcoSize);

//copy the next field in the union, depending on whether
it's a DWORD or a string
switch (ipcoArr.dwOption)
{
case (UInt32)IESettingOptions.INTERNET_PER_CONN_FLAGS:
BitConverter.GetBytes(ipcoArr.dwValue).CopyTo(ipcoBuf,
i * ipcoSize + sizeof(UInt32));
break;
case
(UInt32)IESettingOptions.INTERNET_PER_CONN_PROXY_SERVER:
case
(UInt32)IESettingOptions.INTERNET_PER_CONN_PROXY_BYPASS:
BitConverter.GetBytes(ipcoArr.pszValue.ToInt32()).CopyTo(ipcoBuf,
i * ipcoSize + sizeof(UInt32));
break;
}
}

//copy the buffer to the IntPtr that represents the
INTERNET_PER_CONN_OPTION_LIST
IntPtr pOptions = Marshal.AllocCoTaskMem(numIpcos * ipcoSize);
Marshal.Copy(ipcoBuf, 0, pOptions, numIpcos * ipcoSize);
ipcoList.pOptions = pOptions;

//turn the INTERNET_PER_CONN_OPTION structure into an IntPtr
IntPtr ipcoListPtr =
Marshal.AllocCoTaskMem((Int32)ipcoListSize);
Marshal.StructureToPtr(ipcoList, ipcoListPtr, false);

//call the function to set the settings
bool bRet = InternetSetOption(IntPtr.Zero,
(UInt32)IESettingOptions.INTERNET_OPTION_PER_CONNECTION_OPTION, ipcoList,
ipcoListSize);

if (!bRet)
{
int err = Marshal.GetLastWin32Error();
System.ComponentModel.Win32Exception we = new
System.ComponentModel.Win32Exception(err);
Console.WriteLine("The following error occurred: {0}",
we.Message);
Console.Read();
}

//notify of the change and refresh
InternetSetOption(IntPtr.Zero,
(UInt32)IESettingOptions.INTERNET_OPTION_SETTINGS_CHANGED, ipcoList, 0);
InternetSetOption(IntPtr.Zero,
(UInt32)IESettingOptions.INTERNET_OPTION_REFRESH, ipcoList, 0);

//and deallocate allocated memory
Marshal.FreeCoTaskMem(ipcoList.pOptions);
Marshal.FreeCoTaskMem(ipcoListPtr);
Marshal.FreeHGlobal(ipcoArr[1].pszValue);
Marshal.FreeHGlobal(ipcoArr[2].pszValue);
}
}
 
N

Nicholas Paldino [.NET/C# MVP]

Epetruk,

Perhaps you can simplify things by giving us the details of the crash
and where it is happening?


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

Epetruk said:
Hi,

I wrote this class to try to set the proxy settings in Internet Explorer
programmatically. The class uses the API functions in wininet.dll;
however, there's a horrible crash when I call InternetSetOption the first
time. Can anyone tell me what I'm doing wrong?

Epetruk



public class IESettingsApp
{
public enum IESettingOptions
{
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,
INTERNET_OPTION_REFRESH = 37,
INTERNET_OPTION_PER_CONNECTION_OPTION = 75,
INTERNET_OPTION_SETTINGS_CHANGED = 39,
PROXY_TYPE_PROXY = 2,
PROXY_TYPE_DIRECT = 1,
};

[StructLayout(LayoutKind.Sequential)]
struct FILETIME
{
public UInt32 dwLowDate;
public UInt32 dwHighDate;
};

//special way of handling unions - 2nd, 3rd and 4th fields begin at
same loc
[StructLayout(LayoutKind.Explicit, Size = 12)]
struct INTERNET_PER_CONN_OPTION
{
[FieldOffset(0)]
public UInt32 dwOption;
[FieldOffset(4)]
public UInt32 dwValue;
[FieldOffset(4)]
public IntPtr pszValue;
[FieldOffset(4)]
public FILETIME ftValue;

};

[StructLayout(LayoutKind.Sequential)]
struct INTERNET_PER_CONN_OPTION_LIST
{
public UInt32 dwSize;
public String pszConnection;
public UInt32 dwOptionCount;
public UInt32 dwOptionError;
public IntPtr pOptions;
};

[DllImport("wininet.dll", SetLastError = true, CharSet =
CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
private extern static bool InternetSetOption(IntPtr hInternet,
UInt32 dwOption, INTERNET_PER_CONN_OPTION_LIST lpBuffer, UInt32
dwBufferLength);

public static void SetIEProxySettings(String strProxyServer, String
strProxyBypassAddresses)
{
const int numIpcos = 3;

//create the INTERNET_PER_CONN_OPTION_LIST, and set its size
INTERNET_PER_CONN_OPTION_LIST ipcoList = new
INTERNET_PER_CONN_OPTION_LIST();
UInt32 ipcoListSize = (UInt32)Marshal.SizeOf(ipcoList);
ipcoList.dwSize = ipcoListSize;
ipcoList.pszConnection = null;
ipcoList.dwOptionCount = numIpcos;

INTERNET_PER_CONN_OPTION[] ipcoArr = new
INTERNET_PER_CONN_OPTION[numIpcos];
int ipcoSize = Marshal.SizeOf(ipcoArr[0]);

//use proxy server
ipcoArr[0].dwOption =
(UInt32)(IESettingOptions.INTERNET_PER_CONN_FLAGS);
ipcoArr[0].dwValue =
(UInt32)IESettingOptions.INTERNET_PER_CONN_PROXY_SERVER;

//use *this* proxy server
ipcoArr[1].dwOption =
(UInt32)IESettingOptions.INTERNET_PER_CONN_PROXY_SERVER;
ipcoArr[1].pszValue =
Marshal.StringToHGlobalAnsi(strProxyServer);

bypass these addresses for the proxy
ipcoArr[2].dwOption =
(UInt32)IESettingOptions.INTERNET_PER_CONN_PROXY_BYPASS;
ipcoArr[2].pszValue =
Marshal.StringToHGlobalAnsi(strProxyBypassAddresses);

//now create a buffer that will hold all the
INTERNET_PER_CONN_OPTIONS we've created
byte[] ipcoBuf = new byte[ipcoSize * numIpcos];

for (int i = 0; i < numIpcos; i++)
{
//copy the dwOption first
BitConverter.GetBytes(ipcoArr.dwOption).CopyTo(ipcoBuf,
i * ipcoSize);

//copy the next field in the union, depending on whether
it's a DWORD or a string
switch (ipcoArr.dwOption)
{
case (UInt32)IESettingOptions.INTERNET_PER_CONN_FLAGS:

BitConverter.GetBytes(ipcoArr.dwValue).CopyTo(ipcoBuf, i * ipcoSize +
sizeof(UInt32));
break;
case
(UInt32)IESettingOptions.INTERNET_PER_CONN_PROXY_SERVER:
case
(UInt32)IESettingOptions.INTERNET_PER_CONN_PROXY_BYPASS:

BitConverter.GetBytes(ipcoArr.pszValue.ToInt32()).CopyTo(ipcoBuf, i *
ipcoSize + sizeof(UInt32));
break;
}
}

//copy the buffer to the IntPtr that represents the
INTERNET_PER_CONN_OPTION_LIST
IntPtr pOptions = Marshal.AllocCoTaskMem(numIpcos * ipcoSize);
Marshal.Copy(ipcoBuf, 0, pOptions, numIpcos * ipcoSize);
ipcoList.pOptions = pOptions;

//turn the INTERNET_PER_CONN_OPTION structure into an IntPtr
IntPtr ipcoListPtr =
Marshal.AllocCoTaskMem((Int32)ipcoListSize);
Marshal.StructureToPtr(ipcoList, ipcoListPtr, false);

//call the function to set the settings
bool bRet = InternetSetOption(IntPtr.Zero,
(UInt32)IESettingOptions.INTERNET_OPTION_PER_CONNECTION_OPTION, ipcoList,
ipcoListSize);

if (!bRet)
{
int err = Marshal.GetLastWin32Error();
System.ComponentModel.Win32Exception we = new
System.ComponentModel.Win32Exception(err);
Console.WriteLine("The following error occurred: {0}",
we.Message);
Console.Read();
}

//notify of the change and refresh
InternetSetOption(IntPtr.Zero,
(UInt32)IESettingOptions.INTERNET_OPTION_SETTINGS_CHANGED, ipcoList, 0);
InternetSetOption(IntPtr.Zero,
(UInt32)IESettingOptions.INTERNET_OPTION_REFRESH, ipcoList, 0);

//and deallocate allocated memory
Marshal.FreeCoTaskMem(ipcoList.pOptions);
Marshal.FreeCoTaskMem(ipcoListPtr);
Marshal.FreeHGlobal(ipcoArr[1].pszValue);
Marshal.FreeHGlobal(ipcoArr[2].pszValue);
}
}
 
E

Epetruk

Hello Nicholas,

Thanks for your response.

As I said, the crash occurs whent I call InternetSetOption for the first
time here:

bool bRet = InternetSetOption(IntPtr.Zero,
(UInt32)IESettingOptions.INTERNET_OPTION_PER_CONNECTION_OPTION, ipcoList,
ipcoListSize);

I get an AccessViolationException when I call this.

Sorry for all the code; it's just that I don't know what exactly I am doing
before this call to precipitate the crash, so I thought it would be good for
everything to be shown.

Please let me know if you need any further information.

Epetruk



Nicholas Paldino said:
Epetruk,

Perhaps you can simplify things by giving us the details of the crash
and where it is happening?


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

Epetruk said:
Hi,

I wrote this class to try to set the proxy settings in Internet Explorer
programmatically. The class uses the API functions in wininet.dll;
however, there's a horrible crash when I call InternetSetOption the first
time. Can anyone tell me what I'm doing wrong?

Epetruk



public class IESettingsApp
{
public enum IESettingOptions
{
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,
INTERNET_OPTION_REFRESH = 37,
INTERNET_OPTION_PER_CONNECTION_OPTION = 75,
INTERNET_OPTION_SETTINGS_CHANGED = 39,
PROXY_TYPE_PROXY = 2,
PROXY_TYPE_DIRECT = 1,
};

[StructLayout(LayoutKind.Sequential)]
struct FILETIME
{
public UInt32 dwLowDate;
public UInt32 dwHighDate;
};

//special way of handling unions - 2nd, 3rd and 4th fields begin
at same loc
[StructLayout(LayoutKind.Explicit, Size = 12)]
struct INTERNET_PER_CONN_OPTION
{
[FieldOffset(0)]
public UInt32 dwOption;
[FieldOffset(4)]
public UInt32 dwValue;
[FieldOffset(4)]
public IntPtr pszValue;
[FieldOffset(4)]
public FILETIME ftValue;

};

[StructLayout(LayoutKind.Sequential)]
struct INTERNET_PER_CONN_OPTION_LIST
{
public UInt32 dwSize;
public String pszConnection;
public UInt32 dwOptionCount;
public UInt32 dwOptionError;
public IntPtr pOptions;
};

[DllImport("wininet.dll", SetLastError = true, CharSet =
CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
private extern static bool InternetSetOption(IntPtr hInternet,
UInt32 dwOption, INTERNET_PER_CONN_OPTION_LIST lpBuffer, UInt32
dwBufferLength);

public static void SetIEProxySettings(String strProxyServer,
String strProxyBypassAddresses)
{
const int numIpcos = 3;

//create the INTERNET_PER_CONN_OPTION_LIST, and set its size
INTERNET_PER_CONN_OPTION_LIST ipcoList = new
INTERNET_PER_CONN_OPTION_LIST();
UInt32 ipcoListSize = (UInt32)Marshal.SizeOf(ipcoList);
ipcoList.dwSize = ipcoListSize;
ipcoList.pszConnection = null;
ipcoList.dwOptionCount = numIpcos;

INTERNET_PER_CONN_OPTION[] ipcoArr = new
INTERNET_PER_CONN_OPTION[numIpcos];
int ipcoSize = Marshal.SizeOf(ipcoArr[0]);

//use proxy server
ipcoArr[0].dwOption =
(UInt32)(IESettingOptions.INTERNET_PER_CONN_FLAGS);
ipcoArr[0].dwValue =
(UInt32)IESettingOptions.INTERNET_PER_CONN_PROXY_SERVER;

//use *this* proxy server
ipcoArr[1].dwOption =
(UInt32)IESettingOptions.INTERNET_PER_CONN_PROXY_SERVER;
ipcoArr[1].pszValue =
Marshal.StringToHGlobalAnsi(strProxyServer);

bypass these addresses for the proxy
ipcoArr[2].dwOption =
(UInt32)IESettingOptions.INTERNET_PER_CONN_PROXY_BYPASS;
ipcoArr[2].pszValue =
Marshal.StringToHGlobalAnsi(strProxyBypassAddresses);

//now create a buffer that will hold all the
INTERNET_PER_CONN_OPTIONS we've created
byte[] ipcoBuf = new byte[ipcoSize * numIpcos];

for (int i = 0; i < numIpcos; i++)
{
//copy the dwOption first
BitConverter.GetBytes(ipcoArr.dwOption).CopyTo(ipcoBuf,
i * ipcoSize);

//copy the next field in the union, depending on whether
it's a DWORD or a string
switch (ipcoArr.dwOption)
{
case (UInt32)IESettingOptions.INTERNET_PER_CONN_FLAGS:

BitConverter.GetBytes(ipcoArr.dwValue).CopyTo(ipcoBuf, i * ipcoSize +
sizeof(UInt32));
break;
case
(UInt32)IESettingOptions.INTERNET_PER_CONN_PROXY_SERVER:
case
(UInt32)IESettingOptions.INTERNET_PER_CONN_PROXY_BYPASS:

BitConverter.GetBytes(ipcoArr.pszValue.ToInt32()).CopyTo(ipcoBuf, i *
ipcoSize + sizeof(UInt32));
break;
}
}

//copy the buffer to the IntPtr that represents the
INTERNET_PER_CONN_OPTION_LIST
IntPtr pOptions = Marshal.AllocCoTaskMem(numIpcos * ipcoSize);
Marshal.Copy(ipcoBuf, 0, pOptions, numIpcos * ipcoSize);
ipcoList.pOptions = pOptions;

//turn the INTERNET_PER_CONN_OPTION structure into an IntPtr
IntPtr ipcoListPtr =
Marshal.AllocCoTaskMem((Int32)ipcoListSize);
Marshal.StructureToPtr(ipcoList, ipcoListPtr, false);

//call the function to set the settings
bool bRet = InternetSetOption(IntPtr.Zero,
(UInt32)IESettingOptions.INTERNET_OPTION_PER_CONNECTION_OPTION, ipcoList,
ipcoListSize);

if (!bRet)
{
int err = Marshal.GetLastWin32Error();
System.ComponentModel.Win32Exception we = new
System.ComponentModel.Win32Exception(err);
Console.WriteLine("The following error occurred: {0}",
we.Message);
Console.Read();
}

//notify of the change and refresh
InternetSetOption(IntPtr.Zero,
(UInt32)IESettingOptions.INTERNET_OPTION_SETTINGS_CHANGED, ipcoList, 0);
InternetSetOption(IntPtr.Zero,
(UInt32)IESettingOptions.INTERNET_OPTION_REFRESH, ipcoList, 0);

//and deallocate allocated memory
Marshal.FreeCoTaskMem(ipcoList.pOptions);
Marshal.FreeCoTaskMem(ipcoListPtr);
Marshal.FreeHGlobal(ipcoArr[1].pszValue);
Marshal.FreeHGlobal(ipcoArr[2].pszValue);
}
}

 
C

christery

As I said, the crash occurs whent I call InternetSetOption for the first
time here:

bool bRet = InternetSetOption(IntPtr.Zero,
(UInt32)IESettingOptions.INTERNET_OPTION_PER_CONNECTION_OPTION, ipcoList,
ipcoListSize);

I get an AccessViolationException when I call this.

So if u comment out this line it all works? or do the next line/s
crash?

//CY
 
C

christery

so thats crashing on 75...
IESettingOptions.INTERNET_OPTION_PER_CONNECTION_OPTION
and

public enum IESettingOptions
{
INTERNET_OPTION_PER_CONNECTION_OPTION = 75,

what are u calling?
 
E

Epetruk

Hello CY,

The next calls to InternetSetOption also crash when the problem line is
commented out.

Epetruk
 
E

Epetruk

so thats crashing on 75...
IESettingOptions.INTERNET_OPTION_PER_CONNECTION_OPTION
and

public enum IESettingOptions
{
INTERNET_OPTION_PER_CONNECTION_OPTION = 75,

what are u calling?

I don't understand your question. Do you want to know which function I am
calling when the crash occurs?

Epetruk
 
N

Nicholas Paldino [.NET/C# MVP]

Epetruk,

Did you code all of the structures and P/Invoke declarations by hand?
Or did you get them from somewhere else? More likely than not, you have a
bad declaration somewhere.

Have you checked http://www.pinvoke.net? The declarations there are
more than likely to be correct (moreso than by having coded them by hand).


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

Epetruk said:
Hello Nicholas,

Thanks for your response.

As I said, the crash occurs whent I call InternetSetOption for the first
time here:

bool bRet = InternetSetOption(IntPtr.Zero,
(UInt32)IESettingOptions.INTERNET_OPTION_PER_CONNECTION_OPTION, ipcoList,
ipcoListSize);

I get an AccessViolationException when I call this.

Sorry for all the code; it's just that I don't know what exactly I am
doing before this call to precipitate the crash, so I thought it would be
good for everything to be shown.

Please let me know if you need any further information.

Epetruk



Nicholas Paldino said:
Epetruk,

Perhaps you can simplify things by giving us the details of the crash
and where it is happening?


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

Epetruk said:
Hi,

I wrote this class to try to set the proxy settings in Internet Explorer
programmatically. The class uses the API functions in wininet.dll;
however, there's a horrible crash when I call InternetSetOption the
first time. Can anyone tell me what I'm doing wrong?

Epetruk



public class IESettingsApp
{
public enum IESettingOptions
{
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,
INTERNET_OPTION_REFRESH = 37,
INTERNET_OPTION_PER_CONNECTION_OPTION = 75,
INTERNET_OPTION_SETTINGS_CHANGED = 39,
PROXY_TYPE_PROXY = 2,
PROXY_TYPE_DIRECT = 1,
};

[StructLayout(LayoutKind.Sequential)]
struct FILETIME
{
public UInt32 dwLowDate;
public UInt32 dwHighDate;
};

//special way of handling unions - 2nd, 3rd and 4th fields begin
at same loc
[StructLayout(LayoutKind.Explicit, Size = 12)]
struct INTERNET_PER_CONN_OPTION
{
[FieldOffset(0)]
public UInt32 dwOption;
[FieldOffset(4)]
public UInt32 dwValue;
[FieldOffset(4)]
public IntPtr pszValue;
[FieldOffset(4)]
public FILETIME ftValue;

};

[StructLayout(LayoutKind.Sequential)]
struct INTERNET_PER_CONN_OPTION_LIST
{
public UInt32 dwSize;
public String pszConnection;
public UInt32 dwOptionCount;
public UInt32 dwOptionError;
public IntPtr pOptions;
};

[DllImport("wininet.dll", SetLastError = true, CharSet =
CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
private extern static bool InternetSetOption(IntPtr hInternet,
UInt32 dwOption, INTERNET_PER_CONN_OPTION_LIST lpBuffer, UInt32
dwBufferLength);

public static void SetIEProxySettings(String strProxyServer,
String strProxyBypassAddresses)
{
const int numIpcos = 3;

//create the INTERNET_PER_CONN_OPTION_LIST, and set its size
INTERNET_PER_CONN_OPTION_LIST ipcoList = new
INTERNET_PER_CONN_OPTION_LIST();
UInt32 ipcoListSize = (UInt32)Marshal.SizeOf(ipcoList);
ipcoList.dwSize = ipcoListSize;
ipcoList.pszConnection = null;
ipcoList.dwOptionCount = numIpcos;

INTERNET_PER_CONN_OPTION[] ipcoArr = new
INTERNET_PER_CONN_OPTION[numIpcos];
int ipcoSize = Marshal.SizeOf(ipcoArr[0]);

//use proxy server
ipcoArr[0].dwOption =
(UInt32)(IESettingOptions.INTERNET_PER_CONN_FLAGS);
ipcoArr[0].dwValue =
(UInt32)IESettingOptions.INTERNET_PER_CONN_PROXY_SERVER;

//use *this* proxy server
ipcoArr[1].dwOption =
(UInt32)IESettingOptions.INTERNET_PER_CONN_PROXY_SERVER;
ipcoArr[1].pszValue =
Marshal.StringToHGlobalAnsi(strProxyServer);

bypass these addresses for the proxy
ipcoArr[2].dwOption =
(UInt32)IESettingOptions.INTERNET_PER_CONN_PROXY_BYPASS;
ipcoArr[2].pszValue =
Marshal.StringToHGlobalAnsi(strProxyBypassAddresses);

//now create a buffer that will hold all the
INTERNET_PER_CONN_OPTIONS we've created
byte[] ipcoBuf = new byte[ipcoSize * numIpcos];

for (int i = 0; i < numIpcos; i++)
{
//copy the dwOption first

BitConverter.GetBytes(ipcoArr.dwOption).CopyTo(ipcoBuf, i *
ipcoSize);

//copy the next field in the union, depending on whether
it's a DWORD or a string
switch (ipcoArr.dwOption)
{
case
(UInt32)IESettingOptions.INTERNET_PER_CONN_FLAGS:

BitConverter.GetBytes(ipcoArr.dwValue).CopyTo(ipcoBuf, i * ipcoSize +
sizeof(UInt32));
break;
case
(UInt32)IESettingOptions.INTERNET_PER_CONN_PROXY_SERVER:
case
(UInt32)IESettingOptions.INTERNET_PER_CONN_PROXY_BYPASS:

BitConverter.GetBytes(ipcoArr.pszValue.ToInt32()).CopyTo(ipcoBuf, i *
ipcoSize + sizeof(UInt32));
break;
}
}

//copy the buffer to the IntPtr that represents the
INTERNET_PER_CONN_OPTION_LIST
IntPtr pOptions = Marshal.AllocCoTaskMem(numIpcos *
ipcoSize);
Marshal.Copy(ipcoBuf, 0, pOptions, numIpcos * ipcoSize);
ipcoList.pOptions = pOptions;

//turn the INTERNET_PER_CONN_OPTION structure into an IntPtr
IntPtr ipcoListPtr =
Marshal.AllocCoTaskMem((Int32)ipcoListSize);
Marshal.StructureToPtr(ipcoList, ipcoListPtr, false);

//call the function to set the settings
bool bRet = InternetSetOption(IntPtr.Zero,
(UInt32)IESettingOptions.INTERNET_OPTION_PER_CONNECTION_OPTION,
ipcoList, ipcoListSize);

if (!bRet)
{
int err = Marshal.GetLastWin32Error();
System.ComponentModel.Win32Exception we = new
System.ComponentModel.Win32Exception(err);
Console.WriteLine("The following error occurred: {0}",
we.Message);
Console.Read();
}

//notify of the change and refresh
InternetSetOption(IntPtr.Zero,
(UInt32)IESettingOptions.INTERNET_OPTION_SETTINGS_CHANGED, ipcoList, 0);
InternetSetOption(IntPtr.Zero,
(UInt32)IESettingOptions.INTERNET_OPTION_REFRESH, ipcoList, 0);

//and deallocate allocated memory
Marshal.FreeCoTaskMem(ipcoList.pOptions);
Marshal.FreeCoTaskMem(ipcoListPtr);
Marshal.FreeHGlobal(ipcoArr[1].pszValue);
Marshal.FreeHGlobal(ipcoArr[2].pszValue);
}
}


 
Top