winsxs目录下的不同版本文件都存放在特定命名规则的目录下,比如
C:Windowswinsxs>dirmsil_microsoft.transactions.bridge.resources*
驱动器 C 中的卷是 vista
卷的序列号是 989F-EFF3C:Windowswinsxs 的目录
msil_microsoft.transactions.bridge.resources_b03f5f7f11d50a3a_6.0.6000.16386_zh-cn_1cde5a17d78fb5ec
msil_microsoft.transactions.bridge.resources_b03f5f7f11d50a3a_6.0.6000.16716_zh-cn_1cd75781d79605cf
msil_microsoft.transactions.bridge.resources_b03f5f7f11d50a3a_6.0.6000.20876_zh-cn_060fb27df137fddf
msil_microsoft.transactions.bridge.resources_b03f5f7f11d50a3a_6.0.6001.18000_zh-cn_1cb2dbd3d7e75eb8
msil_microsoft.transactions.bridge.resources_b03f5f7f11d50a3a_6.0.6001.18106_zh-cn_1cb252ffd7e7f8cf
msil_microsoft.transactions.bridge.resources_b03f5f7f11d50a3a_6.0.6001.22221_zh-cn_05e71ebbf18d0b5e
msil_microsoft.transactions.bridge.resources_b03f5f7f11d50a3a_6.0.6002.18005_zh-cn_1c8e610fd838f2cc
0个文件0 字节
7 个目录 5,382,139,904 可用字节
这里的各个部分用下划线分割,其中我们关注的是“6.0.6000.16386”部分,它表示旧文件的版本号,之前则是唯一文件标识,之后是语言,最后部分是散列值(防止名字冲突)。
本工具的设计思想就是删除所有的旧文件。所有满足如下全部条件的目录都会被移动到C:Windowswinsxs_del目录中。
- 存在比自身更新的版本
- 本身不是最新版本
运行工具前的C盘剩余空间:
所列文件总数:
4473 个文件 3,336,376,627 字节
7655 个目录326,840,320 可用字节C:Windowswinsxs_del>
运行工具并且执行命令
for /d %v in(%SystemRoot%winsxs_del*.*) do rd /s /q %v
删除所有可以删除的无用文件之后的剩余空间:
所列文件总数:
52个文件7,555,048 字节
131 个目录 5,383,979,008 可用字节C:Windowswinsxs_del>
工具源代码如下:请保存为winsxs_clear.bat即可。所有不再需要的文件会移动到c:windowswinsxs_del目录中,可以直接进行删除。
执行时候,务必请使用“管理员”权限。
@echooff
rem获取windows版本
setmove_dir=%SystemRoot%winsxs_del
if notexist %move_dir%nul md %move_dir%
setwinver=none
FOR /F"eol=; tokens=4* delims=] " %%i in ('ver') do set winver=%%i
if"%winver%" == "none" goto enover
echowindows version is %winver%, ready to list winsxs dir.
if notexist %SystemRoot%winsxsnul goto enosxs
setver_prefix=%winver:~0,-1%
echolist winsxs finished! now ready to clear duplicatedfiles
echo dir/ad %SystemRoot%winsxs*_%ver_prefix%*
if "%1"== "run-winsxs-generated" goto :lSkipGen
rem准备生成代码
copy /y"%~f0" "%temp%%~nx0" > nul
echo remgenereted code here >>"%temp%%~nx0"
echo:ldcdStat1 >> "%temp%%~nx0"
echo setend4=%%arg:%ver_prefix%=%%>>"%temp%%~nx0"
echogoto ldcdStat2 >> "%temp%%~nx0"
echo:ldcdStat3 >> "%temp%%~nx0"
echo setend4a=%%arg:%winver%=%%>>"%temp%%~nx0"
echogoto ldcdStat4 >> "%temp%%~nx0"
remnotepad "%temp%%~nx0"
"%temp%%~nx0" run-winsxs-generated
goto:EOF
:lSkipGen
FOR /F"eol=; tokens=1-4 delims= " %%a in ('dir /ad%SystemRoot%winsxs*_%ver_prefix%*') do (
if "%%c" =="<DIR>" call:fnDoClear %%d
)
echoclear OK!
goto:EOF
:enover
echocould not get windows version, abort!
goto:EOF
:enosxs
echo notfound %SystemRoot%winsxs! maybe no privilege or lower windows!
echoonly support windows XP and later!
goto:EOF
:fnDoClear
rem arg:dir_name
FOR /F"eol=; tokens=1-14 delims=_" %%g in ("%1") do call:fnDoClearDir %1%%g %%h %%i %%j %%k %%l %%m %%n %%o %%p %%q %%r %%s %%t %%u %%v %%w%%x %%y %%z
goto:EOF
:fnDoClearDir
rem arg:dir_name dir_parts
setd_name=%1
rem检查参数是否匹配 %winver%, 先跳过前两个.同时准备组合新版本匹配名称,nv1存当前版本,nv2存当前的前一个版本
setnv1=%2_%3_
setnv2=%2_%3_
:ldcdCycle
if "%4"== "" goto :EOF
rem 检查是否ver_prefix 开头,如果是则继续检查是否winver,如果不是winver则表示目标存在
setarg=%4
rem setline=set end4=%%arg:%ver_prefix%=%%
rem%line%
gotoldcdStat1
:ldcdStat2
if"%arg%" == "%end4%" goto ldcdNext
rem 检查是否winver 开头
rem setline=set end4a=%%arg:%winver%=%%
rem%line%
gotoldcdStat3
:ldcdStat4
if not"%arg%" == "%end4a%" goto :EOF
rem 至此则为ver_prefix 开头 且 不等于 winver 的目录名,检查最新版本是否存在,存在则可删除旧的
setnewfound=false
for /d%%v in ("%SystemRoot%winsxs%nv1%%winver%.*_%5_*") do (
if exist %%vnul setnewfound=true
)
if"%newfound%" == "true" call:fnDelDir %d_name%
goto:EOF
:ldcdNext
setnv2=%nv1%
setnv1=%nv2%%4_
shift
gotoldcdCycle
:fnDelDir
rem arg:dir
echo del%SystemRoot%winsxs%1
takeown/r /f "%SystemRoot%winsxs%1"
cacls"%SystemRoot%winsxs%1" /t /e /g everyone:f
move"%SystemRoot%winsxs%1" "%move_dir%%1"
goto:EOF