笔记本开热点后导致 Clash TUN 模式断网的解决办法
最近在笔记本上遇到了一个很搞心态的问题:只要用过热点(哪怕后面把热点关了),Clash / Clash Verge / Mihomo 一开 TUN 模式就必定断网。
看内核日志会一直刷报错:
error: dns resolve failed: couldn't find ip折腾了一圈发现是 Windows 热点的锅,这里把原因和自动化解决脚本记录一下。
为什么会断网?
Windows 在开移动热点时,会自动启用系统的 Internet 连接共享(ICS / SharedAccess) 服务。
当我们在 Clash 里开 TUN 模式时,虚拟网卡需要接管全局流量和 DNS 解析。但 Windows 的热点功能即使关闭后,底层的网络共享服务依然会残留旧的 DNS 转发和虚拟适配器绑定,导致 TUN 模式送过来的 DNS 请求直接被卡死丢弃,表现出来就是所有域名都解析失败、整机断网。
在网络适配器设置里把虚拟网卡的「Internet 连接共享」勾选确定,然后再取消勾选保存,就会强制触发系统刷新 HNetCfg,把残留的共享和 DNS 状态清空,TUN 模式立刻就能恢复正常。
手动恢复方法
如果只是偶尔遇到,手动点两下就能解决:
- 按
Win + R输入ncpa.cpl打开网络连接。 - 找到 Clash 的 TUN 虚拟网卡(或者当前联网的物理网卡)。
- 右键选择 属性 -> 切换到 共享 选项卡。
- 勾选「允许其他网络用户通过此计算机的 Internet 连接来连接」,点击确定。
- 再次打开该属性,取消勾选并确定保存。
- 重启一下 Clash 的 TUN 模式即可。
开机自动修复脚本(一键安装)
每次开机都手动点一遍太麻烦了。根据社区的讨论和大佬的代码,写了一个 PowerShell 脚本并打包成一键安装任务,每次开机登录时会在后台静默重置一次 ICS 状态。
使用方法
以管理员身份打开 PowerShell,直接粘贴运行下面的代码即可:
# Install-ResetTunICS.ps1
# 以管理员身份运行!
$scriptPath = "C:\Scripts\reset-tun-ics.ps1"
$logFile = "C:\Scripts\reset-tun-ics.log"
# 1. 确保目标目录存在
$scriptDir = Split-Path $scriptPath -Parent
if (-not (Test-Path $scriptDir)) { New-Item -ItemType Directory -Path $scriptDir -Force | Out-Null }
# 2. 写入脚本
@"
# Reset TUN ICS Script for Clash Verge Rev / Mihomo
# 以管理员身份运行!
`$logFile = "$logFile"
`$maxRetries = 300
`$retryCount = 0
`$logDir = Split-Path `$logFile -Parent
if (-not (Test-Path `$logDir)) { New-Item -ItemType Directory -Path `$logDir -Force | Out-Null }
function Write-Log(`$msg) {
`$timestamp = (Get-Date).ToString("yyyy-MM-dd HH:mm:ss")
`$line = "`$timestamp - `$msg"
`$line | Out-File -FilePath `$logFile -Append -Encoding UTF8
Write-Host `$line
}
Write-Log "Script started. Waiting for TUN adapter..."
while (`$retryCount -lt `$maxRetries) {
try {
`$allAdapters = @(Get-NetAdapter | Where-Object Status -eq 'Up')
`$tunAdapter = `$null
foreach (`$adapter in `$allAdapters) {
`$name = `$adapter.Name
if (`$name -like "*Mihomo*" -or `$name -like "*Meta*" -or `$name -like "*clash*" -or `$name -like "*TUN*") {
`$tunAdapter = `$name
break
}
}
if (`$tunAdapter) {
Write-Log "Found TUN adapter: `$tunAdapter"
`$physAdapter = `$null
foreach (`$adapter in `$allAdapters) {
`$name = `$adapter.Name
if (`$name -ne `$tunAdapter -and `$name -notlike "*Loopback*" -and `$name -notlike "*Bluetooth*") {
`$physAdapter = `$name
break
}
}
if (-not `$physAdapter) {
Write-Log "No physical adapter found, will retry..."
Start-Sleep -Seconds 1
`$retryCount++
continue
}
Write-Log "Found physical adapter: `$physAdapter"
Write-Log "Step 1: Enabling ICS (Public=`$tunAdapter, Private=`$physAdapter)"
`$netShare = New-Object -ComObject HNetCfg.HNetShare
`$connections = `$netShare.EnumEveryConnection | ForEach-Object {
`$props = `$netShare.NetConnectionProps.Invoke(`$_)
[PSCustomObject]@{
Connection = `$_
Name = `$props.Name
Status = `$props.Status
}
}
`$tunConn = `$connections | Where-Object { `$_.Name -eq `$tunAdapter }
`$physConn = `$connections | Where-Object { `$_.Name -eq `$physAdapter }
if (`$tunConn -and `$physConn) {
`$sharingTun = `$netShare.INetSharingConfigurationForINetConnection.Invoke(`$tunConn.Connection)
`$sharingPhys = `$netShare.INetSharingConfigurationForINetConnection.Invoke(`$physConn.Connection)
`$sharingTun.DisableSharing()
`$sharingPhys.DisableSharing()
Start-Sleep -Milliseconds 500
`$sharingTun.EnableSharing(0)
`$sharingPhys.EnableSharing(1)
Write-Log "ICS enabled successfully"
Start-Sleep -Milliseconds 500
`$sharingTun.DisableSharing()
`$sharingPhys.DisableSharing()
Write-Log "ICS disabled successfully"
Write-Log "ICS reset completed for `$tunAdapter and `$physAdapter!"
break
} else {
Write-Log "Could not find connections in HNetCfg."
if (-not `$tunConn) {
`$connections | ForEach-Object { Write-Log " Available: '`$(`$_.Name)'" }
}
}
}
} catch {
Write-Log "Error: `$(`$_.Exception.Message)"
}
`$retryCount++
Start-Sleep -Seconds 1
}
if (`$retryCount -ge `$maxRetries) {
Write-Log "Timeout reached without finding active TUN adapter."
}
"@ | Out-File -FilePath $scriptPath -Encoding UTF8
Write-Host "✅ Script written to $scriptPath" -ForegroundColor Green
# 3. 注册计划任务
$action = New-ScheduledTaskAction -Execute 'powershell.exe' -Argument "-NoProfile -ExecutionPolicy Bypass -WindowStyle Hidden -File `"$scriptPath`""
$trigger = New-ScheduledTaskTrigger -AtLogOn
$principal = New-ScheduledTaskPrincipal -UserId $env:USERNAME -LogonType S4U -RunLevel Highest
$settings = New-ScheduledTaskSettingsSet -AllowStartIfOnBatteries -DontStopIfGoingOnBatteries -Hidden
Register-ScheduledTask -TaskName 'ResetTunICS' -Action $action -Trigger $trigger -Principal $principal -Settings $settings -Force
Write-Host ""
Write-Host "========================================================" -ForegroundColor Green
Write-Host " ✅ 计划任务 ResetTunICS 已成功安装并设置为开机自启!" -ForegroundColor Green
Write-Host " ✅ 脚本已写入 $scriptPath" -ForegroundColor Green
Write-Host "========================================================" -ForegroundColor Green脚本会自动在 C:\Scripts\ 创建脚本文件并注册 Windows 任务计划程序。采用 S4U 登录类型,开机在后台完全静默运行,不会弹黑框,用电池供电时也会正常工作。运行状态可以在 C:\Scripts\reset-tun-ics.log 中查看。