WinSxS文件夹是冗余文件存储的位置,通常位于冗余文件存储的位置C:\Windows在目录路径下,文件夹下存储的主要是系统备份、更新补丁备份,WinSxS随着时间的推移,文件夹将逐渐成为系统盘中最大的文件夹。
WinSxS为什么文件夹继续变大?事实上,WinSxS文件夹的具体功能是组件存储,存储在内部Windows重要的组件功能,比如熟悉的C:\Windows\system32目录。
在WinSxS文件夹主要由三部分组成:
1、与Windows共享;
●
而WinSxS可以删除文件夹,TA自身与C:\Windows\system32目录创建了一个硬链接,因此很难直接查看资源管理器的实际大小,并且需要一定的权限来删除文件夹。请参考下图:
那么我们如何查看文件夹的实际大小呢?
★cmd,然后右击管理员;
命令2Dism.exe /Online /Cleanup-Image /AnalyzeComponentStore,查询当前WinSxS文件夹的实际大小;
?WinSxS文件夹的实际容量小于Windows资源管理器的数据显示。
如何删除WinSxS文件?
.txt后缀为.bat双击打开,跟随命令提示返回,等待命令完成(如果在此过程中有多个拒绝访问字,则证明用户账户的权限不够高)。
如下:
@echo off
set mxms=a
if not "!mxms!" == "a" set mxms=&&%comspec% /V:ON /C %0 %* && goto :EOF
set mxms=
rem 算法描述:
rem windows的winsxs目录中文件夹的格式为:"类型_名字_库id_版本号_语言_签名"
rem 检查所有文件夹。如果发现有不同版本的文件,删除所有旧版本的文件夹
rem 需要注意分也可能包含多个下划线
rem 创建目录
set startT=%TIME%
set move_dir=%SystemRoot%\winsxs_del
if not exist %move_dir%\nul md %move_dir%
set log=%temp%\winsxs-clear.log
pushd "%SystemRoot%\winsxs"
echo ===================== start TE% %TIME% ============================ >> "%log%"
rem 遍历winsxs所有文件夹目录
FOR /F "eol=; tokens=1-4 delims= " %%a in ('dir /ad /o-n %SystemRoot%\winsxs\*.*') do (
if "%%c" == "<DIR>" if exist "%SystemRoot%\winsxs\%%d" call:fnDoClear %%d
)
echo ===================== OK! TE% %TIME% ============================ >> "%log%"
echo clear OK!
echo from %startT% to %TIME%. Check your '%move_dir%' please.
echo view log from %log%
set startT=
set move_dir=
popd
goto :EOF
:fnDoClear
rem arg: dir_name
rem 分解目录名
FOR /F "eol=; tokens=1-14 delims=_" %%g in ("%1") do (
call:fnSplitName %1
if not "%f_type%" == "" call:fnDoClearDir %1 !f_type! !f_name! !f_id! !f_rev! !f_lang! !f_sign!
)
goto :EOF
:fnSplitName
rem arg: dir_name
rem return f_xxx vars
set f_type=
set f_name=
set f_id=
set f_rev=
set f_lang=
set f_sign=
FOR /F "eol=; tokens=1-14 delims=_" %%g in ("%1") do (
if "%%m" == "" (
set f_type=%%g
set f_name=%%h
set f_id=%%i
set f_rev=%%j
set f_lang=%%k
set f_sign=%%l
) else ( if "%%n" == "" (
set f_type=%%g
set f_name=%%h_%%i
set f_id=%%j
set f_rev=%%k
set f_lang=%%l
set f_sign=%%m
) else ( if "%%o" == "" (
set f_type=%%g
set f_name=%%h_%%i_%%j
set f_id=%%k
set f_rev=%%l
set f_lang=%%m
set f_sign=%%n
) else ( if "%%p" == "" (
set f_type=%%g
set f_name=%%h_%%i_%%j_%%k
set f_id=%%l
set f_rev=%%m
set f_lang=%%n
set f_sign=%%o
) else ( if "%%q" == "" (
set f_type=%%g
set f_name=%%h_%%i_%%j_%%k_%%l
set f_id=%%m
set f_rev=%%n
set f_lang=%%o
set f_sign=%%p
) else ( if "%%r" == "" (
set f_type=%%g
set f_name=%%h_%%i_%%j_%%k_%%l_%%m
set f_id=%%n
set f_rev=%%o
set f_lang=%%p
set f_sign=%%q
) else ( if "%%s" == "" (
set f_type=%%g
set f_name=%%h_%%i_%%j_%%k_%%l_%%m_%%n
set f_id=%%o
set f_rev=%%p
set f_lang=%%q
set f_sign=%%r
) else ( if "%%t" == "" (
set f_type=%%g
set f_name=%%h_%%i_%%j_%%k_%%l_%%m_%%n_%%o
set f_id=%%p
set f_rev=%%q
set f_lang=%%r
set f_sign=%%s
) else ( if "%%u" == "" (
set f_type=%%g
set f_name=%%h_%%i_%%j_%%k_%%l_%%m_%%n_%%o_%%p
set f_id=%%q
set f_rev=%%r
set f_lang=%%s
set f_sign=%%t
) else ( if "%%v" == "" (
set f_type=%%g
set f_name=%%h_%%i_%%j_%%k_%%l_%%m_%%n_%%o_%%p_%%q
set f_id=%%r
set f_rev=%%s
set f_lang=%%t
set f_sign=%%u
) else (
echo ERROR: can not split "%1"
)))))))))))))))
)
goto :EOF
:fnDoClearDir
rem arg: dir_name type namespace id revision lang sign
rem 找到最新版本的目录名
call:fnStdVer %5
set curorgver=%5
set curver=%R_STDVER%
set cursign=%7
set R_STDVER=
set newver=
set neworgver=
set newsign=
FOR /F "eol=; tokens=1-4 delims= " %%a in ('dir /ad /o-n %2_%3_%4_*_%6_*') do (
if "%%c" == "<DIR>" (
call:fnSplitName %%d
if not "%f_type%" == "" call:fnCompVer "!newve
)
)
rem 如果找不到,就回去
if "%newver%" == "" goto :EOF
rem 如果找到,清除所有旧版本
echo keep %2_%3_%4 %6 version %neworgver%
echo keep %2_%3_%4 %6 version %neworgver% >> "%log%"
FOR /F "eol=; tokens=1-4 delims= " %%a in ('dir /ad /o-n %2_%3_%4_*_%6_*') do (
if "%%c" == "<DIR>" (
call:fnSplitName %%d
if not "!f_type!" == "" (
if not "!neworgver!" == "!f_rev!" if not "!newsign!" == "!f_sign!" (
echo ... clear %2_%3_%4 %6 version !f_rev!
echo ... clear %2_%3_%4 %6 version !f_rev! >> "%log%"
call:fnDelDir "%%d"
)
)
)
)
goto :EOF
:fnCompVer
rem oldver newver newsign
rem result set var newver
rem 分解ver左侧填充0后,对每个部分进行比较
set V1=%~1
call:fnStdVer %2
set V2=%R_STDVER%
set R_STDVER=
if "%~1" == "" set neworgver=%2&&set newver=%V2%&&set newsign=%3&& goto :EOF
if /I "%V1%" LSS "%V2%" set neworgver=%2&&set newver=%V2%&&set newsign=%3&& goto :EOF
goto :EOF
:fnStdVer
rem arg: ver
FOR /F "eol=; tokens=1-10 delims=." %%v in ("%1") do call:fnStdVerImpl %%v %%w %%x %%y %%z
goto :EOF
:fnStdVerImpl
rem major,minor,revision,build
rem result set in R_STDVER
set svi_1=0000000000%1
set svi_2=0000000000%2
set svi_3=0000000000%3
set svi_4=0000000000%4
set svi_5=0000000000%5
set svi_6=0000000000%6
set R_STDVER=%svi_1:~-10%.%svi_2:~-10%.%svi_3:~-10%.%svi_4:~-10%.%svi_5:~-10%.%svi_6:~-10%
goto :EOF
:fnDelDir
rem arg: dir
echo deleting %SystemRoot%\winsxs\%~1 >> "%log%"
echo --- takeown >> "%log%"
takeown /r /f "%SystemRoot%\winsxs\%~1" >> "%log%"
echo --- takeown = %ERRORLEVEL% >> "%log%"
echo --- cacls >> "%log%"
cacls "%SystemRoot%\winsxs\%~1" /t /e /g everyone:f >> "%log%"
echo --- cacls = %ERRORLEVEL% >> "%log%"
echo --- move >> "%log%"
move "%SystemRoot%\winsxs\%~1" "%move_dir%\%~1" >> "%log%"
echo --- move = %ERRORLEVEL% >> "%log%"
goto :EOF
研究冗余文件比较麻烦。