\r
using System;\r
using System.Runtime.InteropServices;\r
-\r
-// ReSharper disable UnusedMember.Local\r
+using Microsoft.Win32;\r
\r
// ReSharper disable InconsistentNaming\r
\r
{\r
public class SystemProxy\r
{\r
- private InternetPerConnOptionList orgList;\r
- private string _currentUrl;\r
+ private string _prevUrl;\r
+ private const string _regPath = @"Software\Microsoft\Windows\CurrentVersion\Internet Settings";\r
+ private const string _regName = "AutoConfigURL";\r
\r
private void SaveSettings()\r
{\r
- if (orgList.dwSize != 0)\r
+ if (_prevUrl != null)\r
return;\r
- var opts = new[]\r
- {\r
- new InternetPerConnOption {dwOption = PerConnOption.INTERNET_PER_CONN_FLAGS},\r
- new InternetPerConnOption {dwOption = PerConnOption.INTERNET_PER_CONN_AUTOCONFIG_URL}\r
- };\r
- var list = new InternetPerConnOptionList\r
- {\r
- pOptions = MarshalOptions(opts),\r
- pszConnection = IntPtr.Zero,\r
- dwOptionCount = opts.Length,\r
- dwOptionError = 0\r
- };\r
- var listSize = list.dwSize = Marshal.SizeOf(list);\r
- if (InternetQueryOption(IntPtr.Zero, InternetOption.INTERNET_OPTION_PER_CONNECTION_OPTION,\r
- ref list, ref listSize))\r
- {\r
- orgList = list;\r
- }\r
+ using (var regkey = Registry.CurrentUser.OpenSubKey(_regPath))\r
+ _prevUrl = regkey?.GetValue(_regName) as string ?? "delete";\r
}\r
\r
public void SetAutoProxyUrl(string url)\r
{\r
SaveSettings();\r
- var flagValue = new InternetPerConnOptionValue {dwValue = (int)PerConnFlags.PROXY_TYPE_AUTO_PROXY_URL};\r
- var urlValue = new InternetPerConnOptionValue {pszValue = Marshal.StringToHGlobalAuto(url)};\r
- _currentUrl = url;\r
- var opts = new[]\r
- {\r
- new InternetPerConnOption {dwOption = PerConnOption.INTERNET_PER_CONN_FLAGS, Value = flagValue},\r
- new InternetPerConnOption {dwOption = PerConnOption.INTERNET_PER_CONN_AUTOCONFIG_URL, Value = urlValue}\r
- };\r
- var list = new InternetPerConnOptionList\r
- {\r
- pOptions = MarshalOptions(opts),\r
- pszConnection = IntPtr.Zero,\r
- dwOptionCount = opts.Length,\r
- dwOptionError = 0\r
- };\r
- var listSize = list.dwSize = Marshal.SizeOf(list);\r
- var listBuff = Marshal.AllocCoTaskMem(listSize);\r
- Marshal.StructureToPtr(list, listBuff, false);\r
- InternetSetOption(IntPtr.Zero, InternetOption.INTERNET_OPTION_PER_CONNECTION_OPTION, listBuff, listSize);\r
+ using (var regkey = Registry.CurrentUser.OpenSubKey(_regPath, true))\r
+ regkey?.SetValue(_regName, url);\r
+ if (_prevUrl == url) // 同じURLの場合は終了時に設定を消す\r
+ _prevUrl = "delete";\r
Refresh();\r
-\r
- Marshal.FreeHGlobal(urlValue.pszValue);\r
- Marshal.FreeCoTaskMem(list.pOptions);\r
- Marshal.FreeCoTaskMem(listBuff);\r
}\r
\r
public void RestoreSettings()\r
{\r
- if (orgList.dwSize == 0)\r
+ if (_prevUrl == null)\r
return;\r
- var size = Marshal.SizeOf(typeof(InternetPerConnOption));\r
- var urlOpt = (InternetPerConnOption)\r
- Marshal.PtrToStructure((IntPtr)((long)orgList.pOptions + size), typeof(InternetPerConnOption));\r
- var orgUrl = Marshal.PtrToStringAuto(urlOpt.Value.pszValue);\r
- if (orgUrl == _currentUrl) // The restoration was sikipped or failed at last time.\r
+ using (var regkey = Registry.CurrentUser.OpenSubKey(_regPath, true))\r
{\r
- // Unselect the Use automatic configration script check box.\r
- var flagsOpt =\r
- (InternetPerConnOption)Marshal.PtrToStructure(orgList.pOptions, typeof(InternetPerConnOption));\r
- flagsOpt.Value.dwValue &= ~(int)PerConnFlags.PROXY_TYPE_AUTO_PROXY_URL;\r
- Marshal.StructureToPtr(flagsOpt, orgList.pOptions, false);\r
+ if (_prevUrl == "delete")\r
+ {\r
+ regkey?.DeleteValue(_regName, false);\r
+ }\r
+ else\r
+ {\r
+ regkey?.SetValue(_regName, _prevUrl);\r
+ }\r
}\r
- var listSize = orgList.dwSize;\r
- var listBuff = Marshal.AllocCoTaskMem(listSize);\r
- Marshal.StructureToPtr(orgList, listBuff, false);\r
- InternetSetOption(IntPtr.Zero, InternetOption.INTERNET_OPTION_PER_CONNECTION_OPTION, listBuff, listSize);\r
Refresh();\r
-\r
- Marshal.FreeCoTaskMem(listBuff);\r
- Marshal.FreeHGlobal(urlOpt.Value.pszValue);\r
- Marshal.FreeCoTaskMem(orgList.pOptions);\r
- orgList.dwSize = 0;\r
- }\r
-\r
- private IntPtr MarshalOptions(InternetPerConnOption[] opts)\r
- {\r
- var buff = Marshal.AllocCoTaskMem(Marshal.SizeOf(typeof(InternetPerConnOption)) * opts.Length);\r
- var size = Marshal.SizeOf(typeof(InternetPerConnOption));\r
- for (var i = 0; i < opts.Length; i++)\r
- {\r
- var ptr = (IntPtr)((long)buff + (i * size));\r
- Marshal.StructureToPtr(opts[i], ptr, false);\r
- }\r
- return buff;\r
}\r
\r
public static void Refresh()\r
{\r
- InternetSetOption(IntPtr.Zero, InternetOption.INTERNET_OPTION_PROXY_SETTINGS_CHANGED, IntPtr.Zero, 0);\r
+ InternetSetOption(IntPtr.Zero, InternetOption.INTERNET_OPTION_SETTINGS_CHANGED, IntPtr.Zero, 0);\r
+ InternetSetOption(IntPtr.Zero, InternetOption.INTERNET_OPTION_REFRESH, IntPtr.Zero, 0);\r
}\r
\r
[DllImport("WinInet.dll", SetLastError = true, CharSet = CharSet.Auto)]\r
- private static extern bool InternetQueryOption(IntPtr hInternet, InternetOption dwOption,\r
- ref InternetPerConnOptionList optionList, ref int lpdwBufferLength);\r
-\r
- [DllImport("WinInet.dll", SetLastError = true, CharSet = CharSet.Auto)]\r
private static extern bool InternetSetOption(IntPtr hInternet, InternetOption dwOption,\r
IntPtr lpBuffer, int dwBufferLength);\r
\r
- [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]\r
- private struct InternetPerConnOptionList\r
- {\r
- public int dwSize;\r
- public IntPtr pszConnection;\r
- public int dwOptionCount;\r
- public int dwOptionError;\r
- public IntPtr pOptions;\r
- };\r
-\r
- [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]\r
- private struct InternetPerConnOption\r
- {\r
- public PerConnOption dwOption;\r
- public InternetPerConnOptionValue Value;\r
- }\r
-\r
- [StructLayout(LayoutKind.Explicit)]\r
- public struct InternetPerConnOptionValue\r
- {\r
- [FieldOffset(0)] public int dwValue;\r
- [FieldOffset(0)] public IntPtr pszValue;\r
- [FieldOffset(0)] public System.Runtime.InteropServices.ComTypes.FILETIME ftValue;\r
- }\r
-\r
private enum InternetOption : uint\r
{\r
- INTERNET_OPTION_REFRESH = 0x00000025,\r
- INTERNET_OPTION_PER_CONNECTION_OPTION = 0x0000004B,\r
- INTERNET_OPTION_PROXY_SETTINGS_CHANGED = 0x0000005F\r
- }\r
-\r
- private enum PerConnOption\r
- {\r
- INTERNET_PER_CONN_FLAGS = 1,\r
- INTERNET_PER_CONN_PROXY_SERVER = 2,\r
- INTERNET_PER_CONN_PROXY_BYPASS = 3,\r
- INTERNET_PER_CONN_AUTOCONFIG_URL = 4,\r
- INTERNET_PER_CONN_AUTODISCOVERY_FLAGS = 5\r
- }\r
-\r
- [Flags]\r
- private enum PerConnFlags\r
- {\r
- PROXY_TYPE_DIRECT = 0x00000001,\r
- PROXY_TYPE_PROXY = 0x00000002,\r
- PROXY_TYPE_AUTO_PROXY_URL = 0x00000004,\r
- PROXY_TYPE_AUTO_DETECT = 0x00000008\r
+ INTERNET_OPTION_REFRESH = 37,\r
+ INTERNET_OPTION_SETTINGS_CHANGED = 39\r
}\r
}\r
}
\ No newline at end of file