OSDN Git Service

プロキシの設定をレジストリ経由で行う
authorKazuhiro Fujieda <fujieda@users.osdn.me>
Fri, 27 Oct 2017 12:37:49 +0000 (21:37 +0900)
committerKazuhiro Fujieda <fujieda@users.osdn.me>
Sat, 27 Jan 2018 08:33:52 +0000 (17:33 +0900)
KancolleSniffer/SystemProxy.cs

index aeeb032..376d6d6 100644 (file)
@@ -14,8 +14,7 @@
 \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
@@ -23,163 +22,60 @@ namespace KancolleSniffer
 {\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