`
bigtall
  • 浏览: 10334 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

我的Winsxs目录清理脚本

 
阅读更多

最近两天我的C盘空间不够了,竟然只剩几K,真的很晕菜,而且即使使用CCleaner清理也没用,第二天又满了。所以下决心要清理Winsxs目录。之前我的winsxs清理脚本编写过一个版本,发布在我cnblogs的博客中,但是有些bug,在win7下不太好使,今天花了半天重新编制了一下。在上代码之前,先把算法逻辑说一下:

 

c:\windows\winsxs是系统目录,主要是防止臭名昭著的“dll hell”问题而设计的,原先windows升级之后,应用程序常常因为dll被升级了,导致无法正常运行,后来M$启用 winsxs 目录,保存每一个被升级的dll版本,每当应用程序需要使用dll的时候,就把与之对应版本的dll给它用,保证兼容性。

 

winsxs目录中所有的dll版本都存放在特殊格式的目录中,该目录名由以下的几个部分构成(我自己猜的,不一定解释准确),每个部分之间使用下划线连接:

 

  1. 子系统名称,取值一般有x86,amd64,msil等
  2. 库的全称,名称是全称,包含命名空间和库的名称,其中需要注意的是名称中可能会包含下划线,如果名字太长,会用...缩略
  3. 库的id,用于唯一标识库的id,因为简单的库的名称可能会有重复,所以分配一个唯一库id
  4. 版本,库的版本号,包含主版本,次版本,补丁版本和构建号
  5. 语言,如果没有语言则为none
  6. dll的id,也可能是校验码,反正我发现可以用来标识唯一的dll
所以清理winsxs的算法就很简单,找到重复的库,留下最高版本的,删除所有低版本的。这里使用windows的批处理,大家可以直接使用。

运行的时候,记得用“管理员权限”运行。

我刚才运行这个工具之后,发现存放清理结果的winsxs_del文件夹里边有“ 1764 个文件  1,404,255,801 字节”,看来成效还是不错的。

代码如下:

@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 %DATE% %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! %DATE% %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 "!newver!" !f_rev! !f_sign!
    )
)
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
 





 

 

0
3
分享到:
评论
3 楼 rjgcs123 2013-11-21  
我在 C:\Windows\winsxs 目录下创建了个clear.bat 文件,然后管理员取得所有权,再粘贴今天就可以用了,清理了不少文件,非常感谢
2 楼 zhou405680603 2012-06-10  
不能使用啊

提示语法错误
1 楼 kangsg219 2012-03-25  
哥,代码还是有问题呀!执行不了!

相关推荐

    Win7 winsxs目录清理助手 绝对有用!

    3. SlimWinSXS.bat:这是一个批处理文件,很可能就是执行winsxs目录清理的脚本。用户只需运行这个批处理文件,按照提示操作,即可启动清理过程。 总的来说,这款Win7 winsxs目录清理助手是一个方便的实用工具,能够...

    WinSxS目录清理

    WinSxS目录清理

    win7 winsxs文件夹清理

    win7 winsxs文件夹清理,清除没有用的文件。

    WinSxS清理工具.zip

    winsxs清理工具是一款简单易用的系统清理工具,使用它能够帮助用户有效地彻底清除winsxs目录及目录下的所有文件信息,包括更新文件,更新备份文件,临时更新文件,系统日志,installer临时文件等无用信息文件,帮你...

    WIN7WINSXS清理工具

    标题中的“WIN7WINSXS清理工具”是指用于优化Windows 7系统中“Windows\winsxs”目录的软件。这个目录包含了大量的系统组件和DLL文件,随着时间的推移,由于Windows更新和修复安装,该目录可能会变得非常大,占用...

    WinSxS清理工具合集

    为了帮助用户解决这一问题,出现了专门针对WinSxS文件夹清理的工具,如DriverStoreExplorer、Dism++以及WinSXS清理工具。下面将详细介绍这些工具的功能、用途及其如何帮助优化Windows系统。 1. **DriverStore...

    WINsxs文件夹清理程序

    "WINsxs文件夹清理程序" 是一个专为Windows 7系统设计的工具,旨在帮助用户清理Windows系统目录中的WinSxS(Windows Side-by-Side)文件夹。这个文件夹通常包含了大量的系统组件和DLL文件,用于支持不同版本的程序和...

    winsxs 清理小工具

    windos7(win7) 的C:\Windows\winsxs目录非常大,而且不能顺便删除,这个小工具能帮助我们清理多余的文件。 步骤 1、下载clearwinsxs.txt文件放到C:\Windows\winsxs目录下 2、修改clearwinsxs.txt文件为clearwinsxs....

    WinSxS清理

    **WinSxS清理** Windows Side-by-Side (WinSxS) 文件夹是Windows操作系统中的一个重要组件,它存储了系统运行所需的多个版本的组件和库文件,以支持不同应用程序和更新之间的兼容性。然而,随着时间的推移,WinSxS...

    winsxs清理小工具BAT文件

    winsxs目录下的文件都是系统要用的各种...注意:win7下的winsxs文件夹清理,运行后会在windows文件夹中产生一个winsxs_del文件夹,里面的东西可以删除。不过这个程序运行后部分软件会有问题,需要重新安装。请酌情使用。

    WInSXS 清理工具

    "WinSXS 清理工具"就是针对这一问题设计的专业软件,它能够安全地清理WinSxS目录中的无用文件,释放被占用的空间。该工具通常会分析系统状态,识别出不再需要的旧版组件和服务包备份,然后进行安全的删除。这样不仅...

    WinSxS清理工具

    1. **安全清理**:WinSxS清理工具在清理前会进行详尽的检查,确保不会删除任何对系统运行至关重要的文件或组件。这是非常关键的,因为错误地删除WinSxS中的文件可能会导致系统不稳定或无法启动。 2. **智能扫描**:...

    winsxs系统更新清理工具

    标题中的“winsxs系统更新清理工具”指的是Windows操作系统中用于管理系统组件的一个关键部分,名为“Windows Side-by-Side”(WinSxS)文件夹。这个文件夹存储了系统运行所需的各种版本的动态链接库(DLLs)和其他...

    WinSxS清理工具.rar

    "WinSxS清理工具.rar"就是为了帮助用户解决这个问题而设计的。 WinSxS文件夹的用途: 1. **组件存储**:WinSxS存储了系统文件的不同版本,包括系统更新和Service Pack,确保不同应用程序可以使用它们需要的特定版本...

    Window7 WinSxS清理工具

    5. **系统还原点**:在进行 WinSxS 清理前,建议创建一个系统还原点,以防万一清理过程中出现问题,可以通过还原点恢复系统到清理前的状态。 6. **安全性**:尽管 WinSxS 清理工具经过微软官方认证,但在清理之前,...

    winsxs清理工具

    "WinSxS"清理工具主要针对Windows 7操作系统中的一个关键组件——“Windows Side-by-Side”(简称WinSxS)文件夹。这个文件夹在系统中扮演着重要的角色,存储了大量的系统组件和dll文件,以支持不同版本的应用程序和...

    WinSxS系统更新补丁清理工具

    标题中的“WinSxS系统更新补丁清理工具”指的是Windows操作系统中用于处理WinSxS(Windows Side-by-Side)目录中过时系统更新补丁的软件工具。这个工具的主要目的是帮助用户释放磁盘空间,因为随着系统更新的累积,...

    win 7 c盘WinSxS文件夹清理

    本文将详细介绍如何安全地对`WinSxS`文件夹进行清理,以释放C盘的空间。 `WinSxS`文件夹的全称是“Windows Side-by-Side Assembly”,它是Windows的一个关键组成部分,主要负责处理程序和系统组件的版本冲突。在这...

    window系统文件夹WinSXS清理工具

    工具用于清理C盘,本人亲测使用,工具编辑好用,绿色无广告,下载解压即可使用,使用教程见博文,链接:https://blog.csdn.net/Reasally/article/details/128268297

Global site tag (gtag.js) - Google Analytics