公司的卡巴斯基安全软件对Hosts文件锁定了。使用代码创建的CMD进程亦或是直接操作Hosts文件都无法操作,但对手动打开的CMD却能对其进行操作,故想到此办法
- 将输入法默认为英语
- 降低UAC等级,防止UAC弹窗干扰
- 模拟键盘操作启动CMD
- 模拟手动使用CMD修改Hosts
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Diagnostics; using System.Drawing; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.InteropServices; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Windows.Forms; using Microsoft.Win32; namespace 天青色等烟雨.PDC { public partial class PDCForm : Form { //---------切换键盘 // 声明 Windows API 函数 [DllImport("imm32.dll", CharSet = CharSet.Auto)] private static extern IntPtr ImmGetDefaultIMEWnd(IntPtr hWnd); [DllImport("imm32.dll", CharSet = CharSet.Auto)] private static extern bool ImmIsIME(IntPtr hKL); [DllImport("imm32.dll", CharSet = CharSet.Auto)] private static extern IntPtr ImmGetContext(IntPtr hWnd); [DllImport("imm32.dll", CharSet = CharSet.Auto)] private static extern bool ImmSetOpenStatus(IntPtr hIMC, bool bOpen); [DllImport("imm32.dll", CharSet = CharSet.Auto)] private static extern bool ImmReleaseContext(IntPtr hWnd, IntPtr hIMC); [DllImport("user32.dll", CharSet = CharSet.Auto)] private static extern IntPtr GetKeyboardLayout(uint idThread); [DllImport("user32.dll", CharSet = CharSet.Auto)] private static extern IntPtr LoadKeyboardLayout(string pwszKLID, uint Flags); [DllImport("user32.dll", CharSet = CharSet.Auto)] private static extern bool UnloadKeyboardLayout(IntPtr hkl); [DllImport("user32.dll", CharSet = CharSet.Auto)] private static extern IntPtr GetForegroundWindow(); [DllImport("user32.dll", CharSet = CharSet.Auto)] private static extern uint GetWindowThreadProcessId(IntPtr hWnd, IntPtr lpdwProcessId); // 定义键盘布局常量 private const uint KLF_ACTIVATE = 0x00000001; private const string ENGLISH_KEYBOARD_LAYOUT = "00000409"; // 英语(美国)的键盘布局 ID //----------模拟按键 // 导入 Windows API,模拟按键 [DllImport("user32.dll")] private static extern void keybd_event(byte bVk, byte bScan, uint dwFlags, UIntPtr dwExtraInfo); // 定义虚拟键码 private const int VK_LWIN = 0x5B; // WIN 键 private const int VK_R = 0x52; // R 键 private const int KEYEVENTF_KEYUP = 0x02; // 按键释放 public PDCForm() { InitializeComponent(); } private void PDCForm_Load(object sender, EventArgs e) { } //========================================================================================================= //nltest /trusted_domains private void trusted_domains_Click(object sender, EventArgs e) { } //========================================================================================================= private void BtnHosts_Click(object sender, EventArgs e) { // 获取当前前景窗口的句柄 IntPtr hWnd = GetForegroundWindow(); // 获取当前线程的键盘布局 uint threadId = GetWindowThreadProcessId(hWnd, IntPtr.Zero); IntPtr hKL = GetKeyboardLayout(threadId); // 检查当前键盘布局是否是 IME if (ImmIsIME(hKL)) { Console.WriteLine("当前输入法是 IME,正在切换到英语输入法..."); // 加载英语键盘布局 IntPtr englishLayout = LoadKeyboardLayout(ENGLISH_KEYBOARD_LAYOUT, KLF_ACTIVATE); if (englishLayout != IntPtr.Zero) { Console.WriteLine("已切换到英语输入法。"); } else { Console.WriteLine("无法加载英语键盘布局。"); } } else { Console.WriteLine("当前输入法已经是非 IME 输入法(如英语)。"); } //----------------------- // 注册表路径 string registryPath = @"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System"; // 设置UAC等级 int uacLevel = 0; // 1 = 默认等级,2 = 最高等级,0 = 关闭UAC SetUACLevel(registryPath, uacLevel); Console.WriteLine("UAC等级已调整,请重启计算机使更改生效。"); // 禁用输入设备 3000 毫秒(即 3 秒) //InputDisabler.TemporarilyDisableInput(10000); // hosts 文件路径 string hostsFilePath = Path.Combine(Environment.SystemDirectory, "drivers", "etc", "hosts"); // 备份文件路径 string backupFilePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "hosts_backup.txt"); try { // 检查 hosts 文件是否存在 if (File.Exists(hostsFilePath)) { // 复制 hosts 文件到备份路径 File.Copy(hostsFilePath, backupFilePath, overwrite: true); Console.WriteLine($"hosts 文件已备份到: {backupFilePath}"); // 模拟按下 WIN + R keybd_event(VK_LWIN, 0, 0, UIntPtr.Zero); // 按下 WIN 键 keybd_event(VK_R, 0, 0, UIntPtr.Zero); // 按下 R 键 keybd_event(VK_R, 0, KEYEVENTF_KEYUP, UIntPtr.Zero); // 释放 R 键 keybd_event(VK_LWIN, 0, KEYEVENTF_KEYUP, UIntPtr.Zero); // 释放 WIN 键 // 等待 Run 对话框打开 System.Threading.Thread.Sleep(500); // 模拟输入 "cmd" SendKeys.SendWait("cmd"); // 模拟输入 "cmd" 并按下 Enter System.Windows.Forms.SendKeys.SendWait("^(+{ENTER})"); // 等待 CMD 窗口打开 System.Threading.Thread.Sleep(1000); // 模拟输入命令并按下回车键 SendKeys.SendWait("echo. > C:\\Windows\\System32\\drivers\\etc\\hosts{ENTER}"); SendKeys.SendWait("echo 10.21.129.2 pdc.chana.com >> C:\\Windows\\System32\\drivers\\etc\\hosts{ENTER}"); SendKeys.SendWait("ipconfig /flushdns{ENTER}"); System.Threading.Thread.Sleep(2000); SendKeys.SendWait("exit{ENTER}"); } else { Console.WriteLine("未找到 hosts 文件。"); } } catch (UnauthorizedAccessException) { Console.WriteLine("请以管理员身份运行此程序。"); } catch (Exception ex) { Console.WriteLine($"备份 hosts 文件时发生错误: {ex.Message}"); } } //========================================================================================================= static void SetUACLevel(string registryPath, int uacLevel) { try { // 修改注册表中的键值 Registry.SetValue(registryPath, "ConsentPromptBehaviorAdmin", uacLevel, RegistryValueKind.DWord); Registry.SetValue(registryPath, "EnableLUA", 1, RegistryValueKind.DWord); // 启用UAC Console.WriteLine("UAC等级已设置为: " + uacLevel); } catch (Exception ex) { Console.WriteLine("修改注册表时出错: " + ex.Message); } static void SetUACLevel(string registryPath, int uacLevel) { try { // 修改注册表中的键值 Registry.SetValue(registryPath, "ConsentPromptBehaviorAdmin", uacLevel, RegistryValueKind.DWord); Registry.SetValue(registryPath, "EnableLUA", 1, RegistryValueKind.DWord); // 启用UAC Console.WriteLine("UAC等级已设置为: " + uacLevel); } catch (Exception ex) { Console.WriteLine("修改注册表时出错: " + ex.Message); } } } //========================================================================================================= } }