公司的卡巴斯基安全软件对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);
}
}
}
//=========================================================================================================
}
}