Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support DNS Flush for Windows in Python #2529

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
42 changes: 11 additions & 31 deletions readme_template.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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:
Expand Down
35 changes: 21 additions & 14 deletions testUpdateHostsFile.py
Original file line number Diff line number Diff line change
Expand Up @@ -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, _):
Expand Down
13 changes: 6 additions & 7 deletions updateHostsFile.py
Original file line number Diff line number Diff line change
Expand Up @@ -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.")
Expand All @@ -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}"
Expand Down
61 changes: 0 additions & 61 deletions updateHostsWindows.bat

This file was deleted.