From 51a8def556e8bace233fe0334021bcdb173277b2 Mon Sep 17 00:00:00 2001 From: gfyoung Date: Fri, 15 Dec 2023 04:07:59 +0000 Subject: [PATCH 1/3] Support DNS flush for Windows --- testUpdateHostsFile.py | 35 +++++++++++++++++++++-------------- updateHostsFile.py | 13 ++++++------- 2 files changed, 27 insertions(+), 21 deletions(-) diff --git a/testUpdateHostsFile.py b/testUpdateHostsFile.py index 4f580f2e246..f7f04ffc162 100644 --- a/testUpdateHostsFile.py +++ b/testUpdateHostsFile.py @@ -1436,23 +1436,30 @@ def test_flush_darwin_fail(self, _): output = sys.stdout.getvalue() self.assertIn(expected, output) - def test_flush_windows(self): + @mock.patch("subprocess.call", return_value=0) + def test_flush_windows(self, _): with self.mock_property("platform.system") as obj: - obj.return_value = "win32" + obj.return_value = "Windows" + flush_dns_cache() - with self.mock_property("os.name"): - os.name = "nt" - flush_dns_cache() + expected = ( + "Flushing the DNS cache to utilize new hosts " + "file...\nFlushing the DNS cache requires " + "administrative privileges. You might need to " + "enter your password." + ) + output = sys.stdout.getvalue() + self.assertIn(expected, output) - expected = ( - "Automatically flushing the DNS cache is " - "not yet supported.\nPlease copy and paste " - "the command 'ipconfig /flushdns' in " - "administrator command prompt after running " - "this script." - ) - output = sys.stdout.getvalue() - self.assertIn(expected, output) + @mock.patch("subprocess.call", return_value=1) + def test_flush_windows_fail(self, _): + with self.mock_property("platform.system") as obj: + obj.return_value = "Windows" + flush_dns_cache() + + expected = "Flushing the DNS cache failed." + output = sys.stdout.getvalue() + self.assertIn(expected, output) @mock.patch("os.path.isfile", return_value=False) def test_flush_no_tool(self, _): diff --git a/updateHostsFile.py b/updateHostsFile.py index b250556ca94..735b29cc286 100755 --- a/updateHostsFile.py +++ b/updateHostsFile.py @@ -1436,8 +1436,10 @@ def move_hosts_file_into_place(final_file): print( f"Replacing {target_file} requires root privileges. You might need to enter your password." ) + cmds = [f'"cp {filename} {target_file}"'] if platform.system() == "Windows" else ["cp", filename, target_file] + try: - subprocess.run(SUDO + ["cp", filename, target_file], check=True) + subprocess.run(SUDO + cmds, check=True) return True except subprocess.CalledProcessError: print_failure(f"Replacing {target_file} failed.") @@ -1459,12 +1461,9 @@ def flush_dns_cache(): if platform.system() == "Darwin": if subprocess.call(SUDO + ["killall", "-HUP", "mDNSResponder"]): print_failure("Flushing the DNS cache failed.") - elif os.name == "nt": - print("Automatically flushing the DNS cache is not yet supported.") - print( - "Please copy and paste the command 'ipconfig /flushdns' in " - "administrator command prompt after running this script." - ) + elif platform.system() == "Windows": + if subprocess.call(SUDO + ['"ipconfig /flushdns"']): + print_failure("Flushing the DNS cache failed.") else: nscd_prefixes = ["/etc", "/etc/rc.d"] nscd_msg = "Flushing the DNS cache by restarting nscd {result}" From 0143dc6b62e7f368ea3fc676a2111d836250ba5a Mon Sep 17 00:00:00 2001 From: gfyoung Date: Fri, 15 Dec 2023 04:25:02 +0000 Subject: [PATCH 2/3] Drop updateHostsWindows.bat Windows support is now at parity in the Python code. --- updateHostsWindows.bat | 61 ------------------------------------------ 1 file changed, 61 deletions(-) delete mode 100755 updateHostsWindows.bat diff --git a/updateHostsWindows.bat b/updateHostsWindows.bat deleted file mode 100755 index 3b14343f096..00000000000 --- a/updateHostsWindows.bat +++ /dev/null @@ -1,61 +0,0 @@ -:: -:: This script will first create a backup of the original or the current hosts -:: file and save it in a file named "hosts.skel". -:: -:: If the "hosts.skel" file exists, the new hosts file with the customized unified -:: hosts will be copied to the proper path. Next, the DNS cache will be refreshed. -:: -:: THIS BAT FILE MUST BE LAUNCHED WITH ADMINISTRATOR PRIVILEGES -:: Admin privileges script based on https://stackoverflow.com/a/10052222 -:: - -@echo off -title Update Hosts - -:: Check if we are an administrator. If not, exit immediately. -:: BatchGotAdmin -:: Check for permissions -if "%PROCESSOR_ARCHITECTURE%" equ "amd64" ( - >nul 2>&1 "%SYSTEMROOT%\SysWOW64\cacls.exe" "%SYSTEMROOT%\SysWOW64\config\system" -) else ( - >nul 2>&1 "%SYSTEMROOT%\system32\cacls.exe" "%SYSTEMROOT%\system32\config\system" -) - -:: If the error flag set, we do not have admin rights. -if %ERRORLEVEL% neq 0 ( - echo Requesting administrative privileges... - goto UACPrompt -) else ( - goto gotAdmin -) - -:UACPrompt -echo Set UAC = CreateObject^("Shell.Application"^) > "%TEMP%\getadmin.vbs" -set params= %* -echo UAC.ShellExecute "cmd.exe", "/c ""%~s0"" %params:"=""%", "", "runas", 1 >> "%TEMP%\getadmin.vbs" - -wscript.exe "%TEMP%\getadmin.vbs" -del "%TEMP%\getadmin.vbs" -exit /b - -:gotAdmin -cd /d "%~dp0" - -:BackupHosts -:: Backup the default hosts file -if not exist "%WINDIR%\System32\drivers\etc\hosts.skel" ( - copy /v "%WINDIR%\System32\drivers\etc\hosts" "%WINDIR%\System32\drivers\etc\hosts.skel" -) - -:UpdateHosts -:: Update hosts file -py updateHostsFile.py --auto --minimise %* - -:: Copy over the new hosts file in-place -copy /y /v hosts "%WINDIR%\System32\drivers\etc\" - -:: Flush the DNS cache -ipconfig /flushdns - -:: Summary note -pause From 22b8b7f09a63f91c3b1210b81f226efec1cd9aaf Mon Sep 17 00:00:00 2001 From: gfyoung Date: Sun, 17 Dec 2023 19:10:34 +0000 Subject: [PATCH 3/3] Update documentation for BAT file removal --- readme_template.md | 42 +++++++++++------------------------------- 1 file changed, 11 insertions(+), 31 deletions(-) diff --git a/readme_template.md b/readme_template.md index 678b0036328..48482cc7775 100644 --- a/readme_template.md +++ b/readme_template.md @@ -413,37 +413,7 @@ The hosts extensions are also available with the following options: } ``` -## Updating hosts file on Windows - -(NOTE: See also some third-party Hosts managers, listed below.) - -On Linux and macOS, run the Python script. On Windows more work is required due -to compatibility issues so it's preferable to run the batch file as follows: - -```sh -updateHostsWindows.bat -``` - -This file **MUST** be run in command prompt with administrator privileges in the -repository directory. In addition to updating the hosts file, it can also -replace the existing hosts file, and reload the DNS cache. It goes without -saying that for this to work, you must be connected to the internet. - -To open a command prompt as administrator in the repository's directory, do the -following: - -- **Windows XP**: Start → Run → `cmd` -- **Windows Vista, 7**: Start Button → type `cmd` → right-click Command Prompt → - "Run as Administrator" -- **Windows 8**: Start → Swipe Up → All Apps → Windows System → right-click - Command Prompt → "Run as Administrator" -- **Windows 10**: Start Button → type `cmd` → right-click Command Prompt → "Run - as Administrator" - -You can also refer to the "Third-Party Hosts Managers" section for further -recommended solutions from third parties. - -### Warning: Using this `hosts` file in Windows may require disabling DNS Cache service +## Windows Caveat: Using this `hosts` file in Windows may require disabling DNS Cache service Windows has issues with larger hosts files. Recent changes in security within Windows 10 denies access to changing services via other tools except registry @@ -473,6 +443,16 @@ Open a command prompt with administrator privileges and run this command: ipconfig /flushdns ``` +To open a command prompt as administrator, do the following: + +- **Windows XP**: Start → Run → `cmd` +- **Windows Vista, 7**: Start Button → type `cmd` → right-click Command Prompt → + "Run as Administrator" +- **Windows 8**: Start → Swipe Up → All Apps → Windows System → right-click + Command Prompt → "Run as Administrator" +- **Windows 10, 11**: Start Button → type `cmd` → right-click Command Prompt → "Run + as Administrator" + ### Linux Open a Terminal and run with root privileges: