SwitchHosts
repository·master·Indexed 12 days ago
https://github.com/oldj/switchhostsA cross-platform application for managing and quickly switching between hosts files, including system, local, remote, group, and folder entries. Built with Tauri, React, Jotai, and Mantine, version 5.0.1 supports privileged writes to system hosts files across macOS, Windows, and Linux using platform-specific elevation strategies.
What's inside SwitchHosts
- SwitchHosts! is an application designed for quickly switching between different hosts files. It allows users to manage multiple host configurations and toggle between them efficiently.
Manage SwitchHosts data and backups
masterSwitchHosts stores all its data in the
~/.SwitchHostsdirectory (or the.SwitchHostsfolder in the current user's home directory on Windows).Data Structure (v5)
~/.SwitchHosts/manifest.json: Stores the hosts tree.~/.SwitchHosts/entries/: Contains the content of local and remote hosts.~/.SwitchHosts/trashcan.json: Stores entries currently in the trash.~/.SwitchHosts/internal/config.json: Stores user preferences.~/.SwitchHosts/internal/histories/: Stores the history of the system hosts file and executed commands.
Backup Methods
- Full Manual Backup: Copy the entire
~/.SwitchHostsfolder. This preserves everything, including preferences and history. - App Export: Use the export feature within the application. This creates a JSON file containing a backup of the hosts data only; it does not include preferences or history.
Backup SwitchHosts data
masterSwitchHosts stores its data in the
~/.SwitchHostsdirectory (on Windows, this is the.SwitchHostsfolder within your user profile directory).Manual Full Backup
To perform a complete manual backup, copy the entire
~/.SwitchHostsfolder.Data Structure (v5)
~/.SwitchHosts/manifest.json: Stores the hosts tree.~/.SwitchHosts/entries/: Stores local and remote hosts content.~/.SwitchHosts/trashcan.json: Stores entries in the trash.~/.SwitchHosts/internal/config.json: Stores preferences.~/.SwitchHosts/internal/histories/: Stores system hosts and command execution history.
Application Export
Using the export feature within the application generates a hosts data backup in JSON format. Note that this export does not include preferences or history.
Build SwitchHosts from source
masterTo develop or build SwitchHosts yourself, ensure you have the following prerequisites installed:
Development Workflow
- Install dependencies:
npm install - Run in development mode:
npm run tauri:dev
Production Build
To create a production version, run:
npm run tauri:buildThe packaged files will be located in
./src-tauri/target/release/bundle/.# development npm run tauri:dev # production build npm run tauri:build- Install dependencies:
Develop and build SwitchHosts from source
masterTo build SwitchHosts yourself, ensure you have Node.js, Rust, and the necessary Tauri system dependencies installed.
Development Workflow
- Install dependencies:
npm install - Run in development mode:
npm run tauri:dev
Production Build
To create a production build, run
npm run tauri:build. The resulting packaged files will be located in./src-tauri/target/release/bundle/.# development npm run tauri:dev # production build npm run tauri:build- Install dependencies:
Install SwitchHosts
masterYou can install SwitchHosts using the following methods:
- Direct Download: Download the latest pre-built version from the GitHub releases page.
- Chocolatey (Windows): Use the Chocolatey package manager to install via PowerShell.
- Build from Source: Follow the development instructions to build the application manually using Node.js and Rust.
choco install switchhostsBack up SwitchHosts data
masterSwitchHosts stores its data in the
~/.SwitchHostsdirectory (on Windows, this is the.SwitchHostsfolder within your User directory).To perform a full manual backup, copy the entire
~/.SwitchHostsfolder.Note that using the application's internal export feature generates a JSON backup of the hosts data only; it does not include preferences or history records.
Data Structure (v5)
~/.SwitchHosts/manifest.json: Stores the hosts tree.~/.SwitchHosts/entries/: Stores local and remote hosts content.~/.SwitchHosts/trashcan.json: Stores items in the trash.~/.SwitchHosts/internal/config.json: Stores preferences.~/.SwitchHosts/internal/histories/: Stores system hosts and command execution history.
Develop and build SwitchHosts
masterTo develop or build SwitchHosts from source, ensure you have the following prerequisites installed:
Development Workflow
- Install dependencies:
npm install - Start development mode:
npm run tauri:dev
Production Build
To create a production build, run:
npm run tauri:buildThe resulting bundled files will be located in
./src-tauri/target/release/bundle/.# 开发 npm run tauri:dev # 生产构建 npm run tauri:build- Install dependencies:
Manage hosts entry files in `~/.SwitchHosts/entries/`
masterSwitchHosts stores individual host configurations as files within the
entries/directory of the application data folder. Each file is named<id>.hosts, where<id>is a unique identifier (typically a UUID).Key behaviors:
- Newline Normalization: To ensure consistency across different platforms and prevent issues with line offsets, all content is always normalized to LF (
\n) upon reading and writing. Even if you provide CRLF (\r\n) or lone CR (\r) input, the data stored on disk and returned by the API will use LF. - System Application: Platform-native newline conversion (e.g., converting LF to CRLF on Windows) only occurs at the final step when applying the configuration to the actual system hosts file, not within the entry files themselves.
- File Persistence: Moving or renaming a node in the UI does not rename the underlying
.hostsfile.
- Newline Normalization: To ensure consistency across different platforms and prevent issues with line offsets, all content is always normalized to LF (
Security Requirements and Code Signing
masterSwitchHosts uses Apple's code-signing requirements to ensure secure communication between the main app and the privileged daemon.
- App Identity: The daemon verifies that the client is the genuine SwitchHosts app by checking its bundle identifier (
net.oldj.switchhosts) and the Apple Developer Team ID (J5J6USUX2F). - Daemon Identity: The app verifies the daemon's identity by checking that it is signed by the same Team ID. This prevents rogue processes from impersonating the Mach service.
These requirements are used with
xpc_connection_set_codesigning_requirementto establish a trusted connection.- App Identity: The daemon verifies that the client is the genuine SwitchHosts app by checking its bundle identifier (
Application Lifecycle: Hide-to-Tray and Exit Guards
masterSwitchHosts implements a 'lightweight' mode where the application can reside in the system tray without an active main window. This is managed through several lifecycle mechanisms:
hide_at_launch: If enabled, the main window is not created duringsetup. The app stays in the tray. The update checker is deferred until the user explicitly shows the main window via the tray.- Exit Guard: To prevent the application from fully quitting when a user simply closes the last visible window (like a 'Find' window) while in tray mode, a
lightweight_exit_guardis armed. This guard intercepts theExitRequestedevent and prevents the process from exiting unless a true quit command is issued. - macOS Reopen: On macOS, if the app is hidden in the tray and the user clicks the Dock icon, the
Reopenevent is intercepted to calllifecycle::show_main_on_reopen, bringing the main window back to the foreground.
Platform-specific elevation strategies
masterSwitchHosts employs different mechanisms for privilege elevation depending on the operating system:
Platform Mechanism Description macOS HelperA persistent root daemon used for silent writes (available for signed builds). macOS AewpUses AuthorizationExecuteWithPrivilegesfrom the Security framework; prompts the user via OS dialog.Linux PkexecUses pkexec /bin/cpto run the copy command via the desktop environment's polkit agent.Windows UacTriggers a UAC self-relaunch by spawning the application again with the runasverb and a specific internal flag.