GKLBB

当你经历了暴风雨,你也就成为了暴风雨

导航

常见问题修复 --- chrome浏览器白屏

浏览器白屏修复脚本,原理是右键设置兼容模式,保存为1.bat

@echo off
:: 关闭命令回显,执行过程中不在窗口显示每条命令本身,只显示输出结果;
:: 就像后台静默运行,用户看不到执行了哪些指令,只看到最终效果

goto main
:: 无条件跳转到 :main 标签处开始执行;
:: 目的是跳过下面的 :elevate 子程序,避免脚本启动时意外执行提权逻辑

:elevate
:: 定义标签 :elevate,这是一个"提权子程序入口",被 goto 调用时跳转到此处
powershell -WindowStyle Hidden -Command "Start-Process cmd -ArgumentList '/c ""%~f0""' -Verb RunAs" >nul 2>&1
:: 调用 PowerShell 以隐藏窗口模式静默运行;
:: Start-Process cmd:启动一个新的 cmd 进程;
:: -ArgumentList '/c ""%~f0""':让新 cmd 执行当前脚本自身,%~f0 是当前脚本的完整路径;
:: -Verb RunAs:以管理员身份(UAC 提权)运行,会弹出系统的"是否允许此应用更改设备"确认框;
:: >nul 2>&1:将标准输出和错误输出都丢弃,不显示任何信息;
:: 整体效果:悄悄地用管理员权限重新启动本脚本
exit /b
:: 退出当前脚本(/b 表示只退出当前批处理层,不关闭 cmd 窗口);
:: 因为提权后会有新进程接管工作,旧的非管理员进程使命完成,直接退出

:main
:: 定义标签 :main,脚本真正的执行逻辑从这里开始
fltmc >nul 2>&1 || goto elevate
:: fltmc 是 Windows 的"文件系统过滤器管理器"命令,普通用户权限下执行会失败;
:: 这里借用它来检测当前是否已拥有管理员权限:成功则继续,失败(||)则跳转到 :elevate 去提权;
:: 就像门卫检查通行证,没有就去重新办证再回来;
:: >nul 2>&1 丢弃输出,只利用其退出码(成功=0,失败=非0)做判断

:: ========================================
:: 处理 Chrome
:: ========================================
call :fix_browser "chrome" "chrome.exe" ^
    "%ProgramFiles%\Google\Chrome\Application\chrome.exe" ^
    "%ProgramFiles(x86)%\Google\Chrome\Application\chrome.exe" ^
    "%LocalAppData%\Google\Chrome\Application\chrome.exe"
:: 调用通用修复子程序处理 Chrome;
:: call :fix_browser 是调用本脚本内定义的 :fix_browser 子程序,执行完后会返回此处继续向下执行;
:: 传入四个参数:浏览器名称标签、进程名、以及三个候选安装路径(^ 是批处理的换行续行符)

:: ========================================
:: 处理 Edge
:: ========================================
call :fix_browser "edge" "msedge.exe" ^
    "%ProgramFiles%\Microsoft\Edge\Application\msedge.exe" ^
    "%ProgramFiles(x86)%\Microsoft\Edge\Application\msedge.exe" ^
    "%LocalAppData%\Microsoft\Edge\Application\msedge.exe"
:: 调用同一个通用修复子程序处理 Edge,参数换成 Edge 对应的进程名和安装路径;
:: 两个浏览器复用同一套逻辑,避免代码重复,便于维护

exit /b
:: 两个浏览器都处理完毕,脚本主流程结束,正常退出

:: ========================================
:: 子程序:fix_browser
:: 功能:搜索指定浏览器的安装路径,写入兼容性注册表,并重启浏览器
:: 参数说明:
::   %1 —— 浏览器名称(仅用于日志标识,如 "chrome""edge")
::   %2 —— 进程映像名(用于 taskkill,如 "chrome.exe""msedge.exe")
::   %3 —— 候选路径1(64位Program Files)
::   %4 —— 候选路径2(32位Program Files x86)
::   %5 —— 候选路径3(用户LocalAppData)
:: ========================================
:fix_browser
:: 定义子程序标签 :fix_browser,call 调用时跳转到此处执行,执行完后自动返回调用处
setlocal
:: 开启局部变量作用域;
:: 确保本子程序内部设置的变量(如 EXE_PATH)不会泄漏到外部影响其他逻辑;
:: 就像函数拥有自己独立的变量空间,用完自动销毁

set "BROWSER_NAME=%~1"  
:: 去掉参数两端的引号后赋值给 BROWSER_NAME,%~1 中的 ~ 表示去除引号;浏览器名称,仅作标识用
set "PROCESS_NAME=%~2"  
:: 去掉引号后赋值给 PROCESS_NAME;进程映像名,用于 taskkill 终止进程
set "EXE_PATH="         
:: 初始化 EXE_PATH 为空,防止残留上一次调用的旧值干扰本次搜索

:: 在三个候选路径中依次搜索浏览器可执行文件
if exist "%~3" set "EXE_PATH=%~3"                           
:: 检查第一个候选路径(64位安装目录)是否存在,存在则记录路径;%~3 去掉第三个参数的引号
if not defined EXE_PATH if exist "%~4" set "EXE_PATH=%~4"  
:: 第一个没找到时,检查第二个候选路径(32位安装目录);not defined 短路判断,找到了就不再继续检查
if not defined EXE_PATH if exist "%~5" set "EXE_PATH=%~5"  
:: 前两个都没找到时,检查第三个候选路径(用户私有安装目录)

if not defined EXE_PATH (   :: 三个路径都没找到,说明该浏览器未安装
    endlocal                :: 提前结束局部变量作用域,释放本次 setlocal 创建的变量环境
    exit /b                 :: 退出子程序,返回调用处继续执行下一个浏览器的处理
)
if not exist "%EXE_PATH%" ( :: 二次验证:变量有值但文件可能已被删除,再次确认文件真实存在
    endlocal                :: 提前结束局部变量作用域
    exit /b                 :: 退出子程序
)

:: 向 HKLM 和 HKCU 同时写入兼容性配置,确保主进程和所有子进程都能读到该配置
reg add "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers" /v "%EXE_PATH%" /t REG_SZ /d "~ WIN7RTM" /f >nul 2>&1
:: 写入系统级注册表(对所有用户生效);
:: /v "%EXE_PATH%":以浏览器完整路径为键名;
:: /t REG_SZ:值类型为普通字符串;
:: /d "~ WIN7RTM":设置 Windows 7 RTM 兼容模式,让系统为该程序挂载兼容性垫片(Shim);
:: /f:强制覆盖,不弹确认框;>nul 2>&1 静默执行
reg add "HKCU\Software\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers" /v "%EXE_PATH%" /t REG_SZ /d "~ WIN7RTM" /f >nul 2>&1
:: 写入用户级注册表(只对当前用户生效);
:: Chrome/Edge 的 GPU 进程、渲染进程以更低权限运行时优先读取用户级注册表;
:: 两处都写才能保证所有进程都拿到兼容性配置,缺一可能导致部分子进程仍然白屏

taskkill /f /im "%PROCESS_NAME%" >nul 2>&1
:: 强制(/f)终止所有与进程名匹配的浏览器进程;
:: 必须先关闭再重启,否则新写入的注册表兼容性配置对已运行的进程不生效;
:: >nul 2>&1 静默执行,即使进程不存在也不报错
ping -n 2 127.0.0.1 >nul
:: 利用 ping 本机两次的等待时间实现约 1 秒延迟;
:: 给系统足够时间让浏览器进程彻底退出,再执行启动,避免新旧进程冲突
start "" "%EXE_PATH%"
:: 异步启动浏览器(start 不等待程序退出就立即返回);
:: 第一个 "" 是必须提供的窗口标题占位参数,防止路径中含空格时被误解析为标题

endlocal
:: 结束局部变量作用域,本子程序内所有变量自动销毁,不影响外部环境
exit /b
:: 子程序执行完毕,返回 call 调用处,继续执行下一行

 

posted on 2026-04-20 11:27  GKLBB  阅读(42)  评论(0)    收藏  举报