Modifying Proxy Settings within C#
I have the following snippet of code here that im trying to build to automatically change the proxy settings:
public class ProxyManager
{
public static bool UnsetProxy()
{
return SetProxy(null);
}
public static bool SetProxy(string Ip,int Port)
{
return SetProxy(Ip + ":" + Port.ToString());
}
public static bool SetProxy(string ProxyAddress)
{
RegistryKey registry = Registry.CurrentUser.OpenSubKey("Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings", true);
if (ProxyAddress == null)
{
registry.SetValue("P开发者_运维问答roxyEnable", 0);
}
else
{
registry.SetValue("ProxyEnable", 1);
registry.SetValue("ProxyServer", ProxyAddress.ToString());
}
//Force the update!
registry.Clase();
InternetSetOption(IntPtr.Zero, INTERNET_OPTION_SETTINGS_CHANGED, IntPtr.Zero, 0);
InternetSetOption(IntPtr.Zero, INTERNET_OPTION_REFRESH, IntPtr.Zero, 0);
return true;
}
[DllImport("wininet.dll")]
public static extern bool InternetSetOption(IntPtr hInternet, int dwOption, IntPtr lpBuffer, int dwBufferLength);
public const int INTERNET_OPTION_SETTINGS_CHANGED = 39;
public const int INTERNET_OPTION_REFRESH = 37;
}
But for some reason the proxy settings are not being set, I know the method is being executed correctly as I insert an event into the Event Manger after the method is called and that is visible.
For some reason though the proxy settings are not, I'me calling the function like so:
EventManager.WriteEntry("Proxy Settings Enabled");
ProxyManager.SetProxy("10.222.62.65:8080");
My application is a windows service and is running under the authority of the Local System Account which has full privileges.
I suspect that it might be a combination of the fact that you're using the code Registry.CurrentUser
and that it's running under the Local System Account
.
The combination of those two snippets of your question makes me think that you might be changing the settings for the wrong user account? I'd suggest trying to run the service under your account and see if that makes any difference (assuming that this is possible due to UAC etc).
i wrote a similar program for disabling network adapters and changing proxy. It is at tognet.codeplex.com. I have experienced that // Force the update code somehow does not wan to refresh proxy settings on a windows 7 box. If i restart IE and look at the proxy settings again only then it shows the correct state of the proxy.
The reason is that you are changing the registry branch of CURRENT_USER, so there are actually two different branches - for your own user, and for Local System. And when you are running as Windows Service, you are changing the other branch. So actually you set the values, bot for a totally defferent user. So what you need - is to get SID of your user, and then save it somewhere, so your service could use it, and access the correct branch (the one that is owned by your user). The code below tested on Windows 10.
public static RegistryKey? GetCurrentUserKey()
{
var sidString = GetSidFromLocalMachine();
if (string.IsNullOrWhiteSpace(sidString))
{
sidString = WindowsIdentity.GetCurrent().User?.ToString();
}
if (string.IsNullOrWhiteSpace(sidString))
return null;
RegistryKey resultKey = Registry.Users.OpenSubKey(sidString + "\\", true);
return resultKey;
}
public static string GetSidFromLocalMachine()
{
var settingsKey = Registry.LocalMachine.OpenSubKey(regKeyInternetSettings, true);
if (settingsKey != null)
return settingsKey.GetValue(regSid).ToString();
return string.Empty;
}
public static bool SaveSidToLocalMachine(string sid)
{
if (string.IsNullOrWhiteSpace(sid))
return false;
var settingsKey = Registry.LocalMachine.OpenSubKey(regKeyInternetSettings, true);
if (settingsKey == null)
return false;
settingsKey.SetValue("SID", sid);
settingsKey.Close();
return true;
}
You need to call SaveSidToLocalMachine before running the service, or set it manually. Then any time you need to load any registry key from your service, just call
var key = GetCurrentUserKey()?.OpenSubKey(regKeyInternetSettings, true);
key.SetValue("ProxyEnable", 1);
key.Close();
And don't forget to refresh:
InternetSetOption(IntPtr.Zero, INTERNET_OPTION_SETTINGS_CHANGED, IntPtr.Zero, 0);
InternetSetOption(IntPtr.Zero, INTERNET_OPTION_REFRESH, IntPtr.Zero, 0);
精彩评论