我目前正在编写一个需要更改Windows代理设置的C#代理程序。每个在线指南仅更改LAN连接的代理设置(即NAT后面)。这是一个问题,因为中国的许多用户(我的目标受众)直接将PPPoE连接从他们的调制解调器连接到他们的计算机并使用PPPoE软件拨号到DSL(是的,这是非常安全的,所有监听端口都可以看到世界,但事情就是这样。)
我如何更改DSL代理?这很令人担忧,因为查看我的用户统计信息~20%的人没有自动更改代理设置。
答案 0 :(得分:6)
这是一个实用程序示例类。你这样使用它:
static void Main(string[] args)
{
// read direct proxy server (return null if there isn't) of the connection named "MyConn"
string server = ProxyUtilities.GetDirectProxyServer("MyConn");
// set a direct proxy server (set to null to disable) to the connection named "MyConn"
ProxyUtilities.SetDirectProxyServer("MyConn", "myproxy:8080");
}
实用程序类:
public static class ProxyUtilities
{
public static string GetDirectProxyServer(string connectionName)
{
List<INTERNET_PER_CONN_OPTION> options = new List<INTERNET_PER_CONN_OPTION>();
INTERNET_PER_CONN_OPTION option = new INTERNET_PER_CONN_OPTION();
option.dwOption = INTERNET_PER_CONN_PROXY_SERVER;
options.Add(option);
option = new INTERNET_PER_CONN_OPTION();
option.dwOption = INTERNET_PER_CONN_FLAGS;
options.Add(option);
using (var list = INTERNET_PER_CONN_OPTION_LIST.From(connectionName, options))
{
int size = list.dwSize;
if (!InternetQueryOption(IntPtr.Zero, INTERNET_OPTION_PER_CONNECTION_OPTION, list, ref size))
throw new Win32Exception(Marshal.GetLastWin32Error());
List<INTERNET_PER_CONN_OPTION> outOptions = list.Options;
string proxyServer = null;
if ((outOptions[1].Value.dwValue & PROXY_TYPE_PROXY) != 0)
{
proxyServer = Marshal.PtrToStringUni(outOptions[0].Value.pszValue);
}
Marshal.FreeHGlobal(outOptions[0].Value.pszValue);
return proxyServer;
}
}
public static void SetDirectProxyServer(string connectionName, string proxyServer)
{
List<INTERNET_PER_CONN_OPTION> options = new List<INTERNET_PER_CONN_OPTION>();
INTERNET_PER_CONN_OPTION option = new INTERNET_PER_CONN_OPTION();
option.dwOption = INTERNET_PER_CONN_PROXY_SERVER;
option.Value.pszValue = proxyServer == null ? IntPtr.Zero : Marshal.StringToHGlobalUni(proxyServer);
options.Add(option);
option = new INTERNET_PER_CONN_OPTION();
option.dwOption = INTERNET_PER_CONN_FLAGS;
option.Value.dwValue = proxyServer == null ? PROXY_TYPE_DIRECT : PROXY_TYPE_PROXY;
options.Add(option);
try
{
using (var list = INTERNET_PER_CONN_OPTION_LIST.From(connectionName, options))
{
int size = list.dwSize;
if (!InternetSetOption(IntPtr.Zero, INTERNET_OPTION_PER_CONNECTION_OPTION, list, size))
throw new Win32Exception(Marshal.GetLastWin32Error());
}
}
finally
{
Marshal.FreeHGlobal(option.Value.pszValue);
}
}
private const int INTERNET_OPTION_PER_CONNECTION_OPTION = 75;
private const int INTERNET_PER_CONN_FLAGS = 1;
private const int INTERNET_PER_CONN_PROXY_SERVER = 2;
private const int PROXY_TYPE_DIRECT = 0x00000001;
private const int PROXY_TYPE_PROXY = 0x00000002;
[StructLayout(LayoutKind.Explicit)]
private struct INTERNET_PER_CONN_OPTION_Value
{
[FieldOffset(0)]
public int dwValue;
[FieldOffset(0)]
public IntPtr pszValue;
[FieldOffset(0)]
public System.Runtime.InteropServices.ComTypes.FILETIME ftValue;
}
[StructLayout(LayoutKind.Sequential)]
private struct INTERNET_PER_CONN_OPTION
{
public int dwOption;
public INTERNET_PER_CONN_OPTION_Value Value;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
private class INTERNET_PER_CONN_OPTION_LIST : IDisposable
{
public int dwSize;
public string pszConnection;
public int dwOptionCount;
public int dwOptionError;
public IntPtr pOptions;
public static INTERNET_PER_CONN_OPTION_LIST From(string name, IEnumerable<INTERNET_PER_CONN_OPTION> options)
{
INTERNET_PER_CONN_OPTION_LIST list = new INTERNET_PER_CONN_OPTION_LIST();
list.pszConnection = name;
list.pOptions = Marshal.AllocCoTaskMem(options.Sum(o => Marshal.SizeOf(o)));
IntPtr current = list.pOptions;
foreach (var option in options)
{
Marshal.StructureToPtr(option, current, false);
current += Marshal.SizeOf(option);
}
list.dwSize = Marshal.SizeOf(list);
list.dwOptionCount = options.Count();
return list;
}
public List<INTERNET_PER_CONN_OPTION> Options
{
get
{
List<INTERNET_PER_CONN_OPTION> options = new List<INTERNET_PER_CONN_OPTION>();
if (pOptions != IntPtr.Zero)
{
IntPtr current = pOptions;
for (int i = 0; i < dwOptionCount; i++)
{
INTERNET_PER_CONN_OPTION option = (INTERNET_PER_CONN_OPTION)Marshal.PtrToStructure(current, typeof(INTERNET_PER_CONN_OPTION));
current += Marshal.SizeOf(option);
options.Add(option);
}
}
return options;
}
}
public void Dispose()
{
if (pOptions != null)
{
Marshal.FreeCoTaskMem(pOptions);
pOptions = IntPtr.Zero;
}
}
}
[DllImport("wininet.dll", SetLastError = true, CharSet = CharSet.Unicode)]
private extern static bool InternetQueryOption(IntPtr hInternet, int dwOption, INTERNET_PER_CONN_OPTION_LIST list, ref int lpdwBufferLength);
[DllImport("wininet.dll", SetLastError = true, CharSet = CharSet.Unicode)]
private static extern bool InternetSetOption(IntPtr hInternet, int dwOption, INTERNET_PER_CONN_OPTION_LIST list, int lpdwBufferLength);
}