上个月把系统盘从 256G 换到 1T 之前,C 盘红了整整两周。翻了一遍占用排行,Windows 自己占 40G,而Chrome一个人吃掉 9.3G,其中 7G 是AppData里的用户数据和历次版本残留。第一反应当然是打开"设置 - 应用"看看能不能移动,结果发现 Chrome 的卸载项挂在HKCU下面,压根没有"更改安装位置"这个入口。于是就有了这篇东西:在Windows上把Chrome的安装目录挪到 D 盘,并且保证它在后续自动更新之后还能正常工作。整个过程我踩了三个坑,也复现过同事电脑上两种失败方案,下面把能用的、不能用的、以及为什么不能,一次讲明白。
1. 先接受一个事实:Chrome 的安装路径是写死的
1.1 用户级安装:默认躺在 AppData 里
从官网下载的ChromeSetup.exe是用户级安装包(per-user),它不往C:\Program Files放任何东西,而是把程序装到这里:
%LOCALAPPDATA%\Google\Chrome\Application # 展开后就是 C:\Users\<你的用户名>\AppData\Local\Google\Chrome\Application这条路径下面有版本号子目录(形如131.0.6778.86)、chrome.7z压缩包、Installer目录,以及一个指向当前版本的小入口。用户数据——书签、密码、扩展、缓存——则放在同级的User Data目录里。
为什么偏偏是这里?因为用户级安装不需要管理员权限,双击就能装完,企业里普通员工账号也能自助安装。代价是所有数据都堆在系统盘。很多人有个错觉,觉得AppData里的东西"不算安装",实际上 Chrome 的缓存加历史版本残留,几个月就能吃到 10G 以上,比很多正经软件还狠。
1.2 系统级安装:能进 Program Files,但依然不能自选盘符
如果你用企业版 MSI(GoogleChromeStandaloneEnterprise64.msi),或者在安装命令后面跟上--system-level,Chrome 会走系统级安装,落到:
C:\Program Files (x86)\Google\Chrome\Application看起来"正规"多了,但它同样不给浏览对话框。Chromium 的安装器里根本没有"选择目标文件夹"这一步,INSTALLDIR之类的参数在官方包里基本属于摆设。原因并不复杂:Chrome 的自动更新由 Omaha(Google Update)负责,它需要在固定的相对位置找到版本目录、chrome.7z和更新清单。一旦允许用户随便放,更新链路就要处理无数种路径组合,出错概率直线上升。Google 的选择很干脆——不让你选。
1.3 为什么"剪切 + 粘贴"必然翻车
这是最多人踩的第一个坑:既然不让选,那我装完手动拖过去总行吧?拖动的一瞬间,Chrome 就打不开了,或者打开了但扩展全消失、提示配置文件损坏。
原因有三层,一层比一层深。
第一层是快捷方式。桌面、任务栏、开始菜单里的快捷方式写的是绝对路径,文件一走,指向的就是空气。
第二层是注册表记录。Chrome 和 Google Update 会在HKCU\Software\Google\Update与HKLM\SOFTWARE\WOW6432Node\Google\Update下面登记客户端信息,里面有版本号、安装路径、卸载串。系统的"应用和功能"列表、更新器的自检逻辑,读的都是这些值。文件搬走了,值还指着老地方,于是"应用和功能"里点卸载直接报错,更新器则认为这次安装已经损坏。
第三层是通用规律:Office、WPS、通达信这类软件都依赖注册表登记安装信息,不只是 Chrome 有这个问题。任何"手动把安装目录搬走"的做法,都绕不开上面三层。所以正确的思路不是"搬走文件",而是"让原来的路径依然能找到文件"——这就引出了下面要讲的目录联接。
2. 三条路摆在面前,只有一条能长期用
2.1 重装法:能换"级别",换不了盘符
网上流传最广的说法是"卸载重装,用 MSI 就能自定义路径"。实测下来,MSI 只能把你从用户级带到系统级,路径依然锁死在Program Files。它真正有价值的地方在于:多用户共用一份程序、配合组策略统一管理、卸载更干净。
所以结论很清楚——只想让 Chrome 从AppData挪到Program Files,重装法有效;目标是挪到 D 盘,重装法帮不上忙。
2.2 目录联接法:唯一能做到"路径不变、文件在别处"
NTFS 的**目录联接(Junction)**是一种重解析点。可以把它理解成"给文件夹挂一个传送门":C:\Users\你\AppData\Local\Google\Chrome这个位置看起来还在,程序访问它的时候,系统会把请求转发到D:\Apps\Chrome。
关键点有这么几个:
- 对 Chrome 来说路径没变,注册表、快捷方式、更新器全部照旧工作;
- 对磁盘来说,实际数据落在 D 盘;
- 创建联接不需要管理员权限(这点和符号链接不同,符号链接要提权或开开发者模式);
- 删除联接本身不会连带删除目标数据,但命令写错就不好说了,后文会专门讲。
这是我实际用下来最稳的方案,也是下面实操部分的主线。
2.3 只改注册表路径:看着最"正宗",其实最脆
还有一套方案是:文件搬到 D 盘,然后把更新器记录里的安装路径值改成新路径。理论成立,实操有两个问题。一是路径记录散落在多个键下面,漏改一个就出问题;二是 Chrome 自动更新时会重新校验并可能写回原值,下次更新完你就得到一个半残的安装。单独用这一招,我不推荐。
2.4 三条路的横向对比
| 方案 | 能否换盘 | 更新后是否稳定 | 需要管理员 | 回滚难度 | 适用场景 |
|---|---|---|---|---|---|
| 卸载重装为系统级 | 只能到 Program Files | 稳定 | 是 | 低 | 多用户共用一台机器 |
| 目录联接(Junction) | 任意本地 NTFS 盘 | 稳定 | 否 | 低 | 个人机省 C 盘空间 |
| 只改注册表路径 | 能 | 不稳定 | 是 | 高 | 不推荐单独使用 |
3. 动手之前,把这几件事先做掉
3.1 彻底退出 Chrome,包括背后那两个"幽灵进程"
只关窗口是不够的。Chrome 默认开启"关闭后继续运行后台应用",托盘里可能还挂着图标;更新器GoogleUpdate.exe也可能正在后台检查。
操作顺序建议这样走:
- 地址栏输入
chrome://settings/system,关掉"关闭 Google Chrome 后继续运行后台应用"; - 打开任务管理器,找
chrome.exe、GoogleUpdate.exe、GoogleCrashHandler.exe,全部结束; - 在任务计划程序里找名字带
GoogleUpdateTaskUser的计划任务,先"禁用"——这一步不是必须,但能避免复制过程中更新器突然干活,把文件锁住。
提示:复制时如果提示"文件正在使用",八成是还有 chrome.exe 没退干净,或者某个扩展的进程在跑。别用强制结束硬扛,先把浏览器真的关干净。
3.2 备份真正值钱的东西
User Data目录里,真正不能丢的是这几样:
User Data\Default\Bookmarks——书签,一个无扩展名的 JSON 文件;User Data\Default\Login Data——保存的密码,SQLite 数据库,需要和Login Data For Account一起带走;User Data\Default\Preferences——设置项;User Data\Default\Extensions——本地解包的扩展(商店装的不必管);User Data\Local State——加密密钥,脱离它密码库解不开。
最省事的做法是把整个User Data目录复制一份到别的盘。不要用剪切,复制完成、验证 Chrome 能正常打开、书签密码都在之后,再决定要不要清理老目录。
3.3 目标盘的两个硬条件
- 必须是本地卷。联接不能指向网络共享路径,也不要指向 U 盘或移动硬盘——拔盘就崩。
- 文件系统用 NTFS。exFAT 和 FAT32 不支持重解析点,权限行为也对不上。
- 顺手看一眼剩余空间:按 Chrome 目录当前大小乘以 1.2 留余量,因为更新时会临时解压
chrome.7z。
4. 完整实操:把 Chrome 搬到 D:\Apps\Chrome
4.1 第一步:复制,而不是剪切
先建目标目录,比如D:\Apps\Chrome,然后把整个C:\Users\<用户名>\AppData\Local\Google\Chrome的内容复制过去。
推荐用robocopy而不是鼠标拖拽,因为 Chrome 目录里有大量小文件和深层路径,资源管理器偶尔会静默跳过:
robocopy "%LOCALAPPDATA%\Google\Chrome" "D:\Apps\Chrome" /E /COPYALL /R:1 /W:1 /NFL /NDL参数逐个说明:
/E复制所有子目录,包含空目录;/COPYALL保留权限、属性、时间戳,Chrome 对目录权限比较敏感;/R:1 /W:1出错只重试一次、等一秒,避免卡在某个被占用的文件上;/NFL /NDL不刷屏列文件名,日志干净好读。
复制完之后对比两边的大小。差几 MB 可能是缓存文件在变,差几百 MB 就是没复制全,回头重来。
4.2 第二步:把原目录改名,而不是删除
把%LOCALAPPDATA%\Google\Chrome重命名为Chrome_bak。这一步的意义在于,联接创建失败、Chrome 起不来的时候,你还有一条退路。
注意:改名之前确认 Chrome 已经彻底退出。如果改名提示"文件夹正在使用",回到 3.1 重新清一遍进程。
4.3 第三步:创建目录联接
用普通命令提示符就行(Junction 不需要提权):
mklink /J "%LOCALAPPDATA%\Google\Chrome" "D:\Apps\Chrome"看到"为 xxx <<===>> xxx 创建的联接"就成功了。
PowerShell 下的等价写法:
New-Item -ItemType Junction -Path "$env:LOCALAPPDATA\Google\Chrome" -Target "D:\Apps\Chrome"mklink的参数顺序是先链接、后目标,写反了会报错。另外链接路径必须不存在,所以务必先把原来的Chrome目录改名。
如果只想搬程序、把User Data留在 C 盘,也可以只对Application子目录做联接。但多数人的痛点是用户数据太大,整体搬更划算。
4.4 第四步:验证,别只看能不能打开
打开 Chrome,然后依次确认这几件事:
- 地址栏输入
chrome://version,看"配置文件路径"和"可执行文件路径"。走联接的情况下,这里通常仍然显示C:\Users\...\AppData\Local\Google\Chrome\...,这是正常的,因为联接对上层应用是透明的; - 书签、密码、扩展是否都在;
- 打开
D:\Apps\Chrome,确认文件确实在活动(浏览几个网页后 Cache 目录应该变大); - 打开
chrome://settings/help触发一次更新检查,看能否正常下载并重启生效。
如果你非要在界面上看到 D 盘路径,那就只能用"改注册表"那条野路子,代价就是 2.3 里说的不稳定。
4.5 第五步:注册表到底要不要动
走完整的目录联接,一个字都不用改。因为 Chrome 和 Google Update 记录的路径依然是%LOCALAPPDATA%\Google\Chrome\...,而这个路径通过联接依然有效。
只有当目标是"只搬 Application、不搬 User Data"并且想让更新器直接认 D 盘时,才需要去碰Google\Update下面的客户端记录。即便这样,我也建议先跑一段时间观察,每次 Chrome 大版本更新后回来看一眼chrome://version和D:\Apps\Chrome里的版本号子目录是不是同步出现了。
5. 这几个坑,我在真实机器上全撞过
5.1 更新后 C 盘又长出一个 Chrome 目录
现象:迁移完过了一两周,C 盘空间又少几个 G,一看AppData\Local\Google下面出现了两个 Chrome 目录。
原因基本是两种:一是当初只联接了Chrome的一部分路径,Installer之类没覆盖到,更新器在"缺失"的位置重建了目录;二是复制时漏了隐藏文件,更新器校验不过,干脆重新下载了一份。
排查方法很直接:先看D:\Apps\Chrome里的版本子目录是不是最新的。如果 D 盘版本落后,说明更新其实写到了 C 盘那个新目录里,那就把新目录删掉,重新做一次完整联接。
5.2 杀软和"清理大师"会把联接当成异常
部分安全软件、系统优化工具,会把重解析点识别为"可疑的目录伪装",然后顺手帮你"修复"——修复的结果就是联接被删、目录被重建,Chrome 又回到了 C 盘。
处理办法是在防护规则里把%LOCALAPPDATA%\Google和你的目标盘目录加白名单。企业环境更要留意,终端管控策略可能直接禁止重解析点,这种情况只能退回"系统级安装到 Program Files"。
5.3 别把目标目录放进 OneDrive 之类的同步盘
有人图省事,把目标设成OneDrive\Apps\Chrome。结果是同步客户端疯狂上传Cache、Code Cache、GPUCache这几个目录,几十万个小文件排队同步,网盘直接卡死,Chrome 也因为文件被锁频繁报错。
要搬就搬到不参与同步的本地目录,D:\Apps\...这种最省心。
5.4 多用户登录的场景
一台机器上有多个 Windows 账号时,每个账号的%LOCALAPPDATA%是独立的。你只做了当前账号的联接,换个人登录,他还是往自己的AppData里装。
只给一个账号做联接不会影响其他人,但磁盘占用统计会很乱。真正的多用户场景,建议直接用系统级 MSI 装到Program Files,再对Program Files\Google\Chrome做一次全局联接。
5.5 Chrome 109 与老系统:迁移时顺手能做的事
还在用 Windows 7 / 8.1 的机器,通常被固定在 Chrome 109 这个最后的兼容版本上。这类机器做目录迁移有个额外好处:可以把自动更新彻底关掉,避免更新器把不兼容的新版本推下来。
关更新的常见做法是禁用GoogleUpdate相关的计划任务和服务,再配合组策略把更新地址指向空。这里必须提醒一句:关掉更新等于放弃安全修复,只在完全离线、内网隔离的机器上这么干,联网机器别图省事。
6. 想反悔怎么办,以及这套路还能用在哪些软件上
6.1 三步回滚
- 完全退出 Chrome 和更新器;
- 删掉联接:
rmdir "%LOCALAPPDATA%\Google\Chrome"。注意是rmdir不是rmdir /s,因为联接本身不是真目录,rmdir只会摘掉链接,不会删 D 盘里的数据(保险起见,先把 D 盘目录再备份一份); - 把之前的
Chrome_bak改回Chrome,启动验证。
如果第 2 步手抖加了/s,数据可能真的被删。这条命令执行前,务必再确认一次目标盘的数据有备份。
6.2 图形化的小工具值不值得用
不想记命令的话,Link Shell Extension这类资源管理器扩展挺好用:选中目标文件夹,右键"选择链接源",再到目标位置右键"创建联接"。适合偶尔用一次的人。
但它有个习惯性风险——菜单里 Symbolic Link、Hardlink、Junction 挨在一起,点错一个,创建出来的东西行为完全不同。如果指望它长期维护多台机器,我还是建议写一个批处理脚本固定下来,参数不用记,双击就跑。
6.3 这套"联接大法"的通用版
理解了原理之后,会发现它不只能用在 Chrome 上。凡是安装路径写死、又不给改目录、同时又很占空间的软件,都可以这么办:
| 软件 | 默认占位大户 | 迁移建议 |
|---|---|---|
| Chrome / Edge | %LOCALAPPDATA%下的程序与缓存 | 整体联接,避开同步盘 |
| VS Code | %USERPROFILE%\.vscode\extensions | 单独联接扩展目录更稳 |
| Docker Desktop | %LOCALAPPDATA%\Docker与虚拟磁盘 | 优先在设置里改磁盘映像位置 |
| Elasticsearch | data与logs目录 | 改配置文件而不是做联接 |
| 各类开发工具链 | npm / pip / Maven 缓存 | 用环境变量或配置指定路径 |
这里有个原则值得记下来:软件自己提供了改路径的配置项,就优先用配置项,比如 Elasticsearch 的path.data、Docker 的磁盘映像设置。只有当软件压根不提供,或者提供了但路径写死在注册表里,才动用联接。联接是兜底手段,不是第一选择。
6.4 最后一点个人经验
我手上三台开发机都做了 Chrome 迁移,最久的一台跑了两年多,中间经历了二十来次大版本更新,没出现过版本错乱。唯一一次翻车是同事的机器上装了某款"系统加速"工具,悄悄把联接清理掉了,表现是"Chrome 突然变回 C 盘、书签还在但缓存全空"。
所以迁移完成之后,我建议你过两周回来看一眼D:\Apps\Chrome的版本子目录有没有跟着更新。这一步花十秒钟,能省掉后面半小时的排查。