剛使用Win7 系統(tǒng)不久,前段時(shí)間在清理系統(tǒng)垃圾時(shí)發(fā)現(xiàn),win7系統(tǒng)的windows目錄下的winsxs 目錄占用空間非常大,想清理之,卻提示無(wú)權(quán)限無(wú)法清理。隨即在網(wǎng)上查了個(gè)究竟,原來(lái)winsxs是一個(gè)超大的文件倉(cāng)庫(kù),系統(tǒng)所在分區(qū)幾乎所有的系統(tǒng)文件都在那里至少有一個(gè)備份。而且隨著系統(tǒng)的使用,winsxs的所占的空間還將不斷的積累壯大,最終將吞噬整個(gè)系統(tǒng)分區(qū)的磁盤(pán)空間。下面附上搜索來(lái)的一篇winsxs的詳細(xì)描述文摘、winsxs的瘦身方法和一篇關(guān)于 DLL Hell問(wèn)題 的描述文摘和大家分享:
winsxs的詳細(xì)描述文摘:
***
winsxs的文件夾位于Windows根目錄,是一個(gè)超大的文件倉(cāng)庫(kù),系統(tǒng)所在分區(qū)幾乎所有的系統(tǒng)文件都在那里至少有一個(gè)備份。有興趣的網(wǎng)友不妨通過(guò)搜索功能在winsxs搜一下公用視頻、公用圖片、公用音樂(lè)文件夾里的文件,你會(huì)發(fā)現(xiàn)那些精簡(jiǎn)系統(tǒng)時(shí)已經(jīng)被刪除了的文件在winsxs里還可以找到影子。假如系統(tǒng)文件被刪除或者破壞,用命令sfc /scannow就可以恢復(fù),但如果將winsxs里面的任何一個(gè)重要的組件刪除,sfc命令就會(huì)失效。系統(tǒng)在線更新的過(guò)程是舊版本文件被新版本的取代,舊文件自動(dòng)備份在winsxs里;卸載補(bǔ)丁的過(guò)程是系統(tǒng)新版本文件被舊版本的取代,而舊版本文件的來(lái)源正是winsxs。XP也有類(lèi)似的功能,但XP下備份文件是可以直接刪除的,Vista和Win7下不行。所以Vista和Win7占用的空間隨著更新增多會(huì)越來(lái)越大,而且大得驚人。winsxs里的文件非常重要,建議不要?jiǎng)h除,以我長(zhǎng)期的實(shí)踐經(jīng)驗(yàn),暫時(shí)發(fā)現(xiàn)只有ManifestCache和Temp兩個(gè)文件夾里的緩存文件才可以安全刪除。
特別提醒:網(wǎng)上所有精簡(jiǎn)winsxs的方法都有一定的危險(xiǎn)性(微軟官方的工具除外),例如“刪除Backup文件夾或用空文件取代同名文件”,雖然它叫Backup,但里面絕對(duì)不是備份文件而是關(guān)系到系統(tǒng)能否正常更新和正常“打開(kāi)或關(guān)閉Windows功能”的重要文件,某些大量被轉(zhuǎn)載的文章都在誤導(dǎo)人。某軟件提供刪除Windows內(nèi)置字體,幫助文件的方法,其實(shí)這對(duì)于精簡(jiǎn)系統(tǒng)是沒(méi)有任何意義的,字體和幫助文件在winsxs還有一個(gè)備份,兩個(gè)相同的文件共用一個(gè)儲(chǔ)存空間,換句話說(shuō),刪除前和刪除后C盤(pán)可用空間不變!但是注意,如果你查看文件或者文件夾的屬性,他們都會(huì)占空間。又如有人提出刪除winsxs里同名文件較低版本的一個(gè)或幾個(gè),這是一個(gè)很好的想法,但問(wèn)題是有些同名文件的不同版本都有重要作用,都不能刪除,例如.Net Framework的相關(guān)組件。
***
winsxs的瘦身方法:
***
清理winsxs的小工具
因?yàn)榇疟P(pán)空間不夠了,所以想起來(lái)清理一下系統(tǒng)垃圾文件,主要目標(biāo)就是臭名昭著的winsxs目錄。這個(gè)winsxs就是微軟為了解決“dll hell”問(wèn)題,結(jié)果是好比在windows系統(tǒng)里安置了一個(gè)毫無(wú)節(jié)制不斷增大的“腫瘤”。聽(tīng)說(shuō)微軟研究院現(xiàn)在在研究這個(gè)問(wèn)題,不過(guò)我想我的硬盤(pán)空間不夠大,等不到這個(gè)補(bǔ)丁出來(lái)的時(shí)候,所以只好自己動(dòng)手了。
winsxs目錄下的文件都是系統(tǒng)要用的各種庫(kù)文件,system32下存放了這些dll的最新的版本,所有老版本的dll都放在winsxs下。所以只要你安裝程序或者更新補(bǔ)丁,system32下的文件就會(huì)被更新,而同時(shí)winsxs就會(huì)增加一些舊文件,所以我們的C盤(pán)空間就在持續(xù)不斷地減少,直到磁盤(pán)容量不夠,被迫重裝系統(tǒng)為止,如果你足夠幸運(yùn),可以直接安裝最新的SP的話,或許可以為winsxs節(jié)約一點(diǎn)微薄的空間。
winsxs目錄下的不同版本文件都存放在特定命名規(guī)則的目錄下,比如
C:/Windows/winsxs>dir msil_microsoft.transactions.bridge.resources*
驅(qū)動(dòng)器 C 中的卷是 vista
卷的序列號(hào)是 989F-EFF3
C:/Windows/winsxs 的目錄
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 個(gè)文件 0 字節(jié)
7 個(gè)目錄 5,382,139,904 可用字節(jié)
這里的各個(gè)部分用下劃線分割,其中我們關(guān)注的是“6.0.6000.16386”部分,它表示舊文件的版本號(hào),之前則是唯一文件標(biāo)識(shí),之后是語(yǔ)言,最后部分是散列值(防止名字沖突)。
本工具的設(shè)計(jì)思想就是刪除所有的舊文件。所有滿足如下全部條件的目錄都會(huì)被移動(dòng)到C:/Windows/winsxs_del目錄中。
存在比自身更新的版本
本身不是最新版本
運(yùn)行工具前的C盤(pán)剩余空間:
所列文件總數(shù):
4473 個(gè)文件 3,336,376,627 字節(jié)
7655 個(gè)目錄 326,840,320 可用字節(jié)
C:/Windows/winsxs_del>
運(yùn)行工具并且執(zhí)行命令
for /d %v in (%SystemRoot%/winsxs_del/*.*) do rd /s /q %v
刪除所有可以刪除的無(wú)用文件之后的剩余空間:
所列文件總數(shù):
52 個(gè)文件 7,555,048 字節(jié)
131 個(gè)目錄 5,383,979,008 可用字節(jié)
C:/Windows/winsxs_del>
工具源代碼如下:請(qǐng)保存為winsxs_clear.bat即可。所有不再需要的文件會(huì)移動(dòng)到c:/windows/winsxs_del目錄中,可以直接進(jìn)行刪除。
執(zhí)行時(shí)候,務(wù)必請(qǐng)使用“管理員”權(quán)限。
@echo off
rem 獲取windows版本
set move_dir=%SystemRoot%/winsxs_del
if not exist %move_dir%/nul md %move_dir%
set winver=none
FOR /F "eol=; tokens=4* delims=] " %%i in ('ver') do set winver=%%i
if "%winver%" == "none" goto enover
echo windows version is %winver%, ready to list winsxs dir.
if not exist %SystemRoot%/winsxs/nul goto enosxs
set ver_prefix=%winver:~0,-1%
echo list winsxs finished! now ready to clear duplicated files
echo dir /ad %SystemRoot%/winsxs/*_%ver_prefix%*
if "%1" == "run-winsxs-generated" goto :lSkipGen
rem 準(zhǔn)備生成代碼
copy /y "%~f0" "%temp%/%~nx0" > nul
echo rem genereted code here >> "%temp%/%~nx0"
echo :ldcdStat1 >> "%temp%/%~nx0"
echo set end4=%%arg:%ver_prefix%=%%>> "%temp%/%~nx0"
echo goto ldcdStat2 >> "%temp%/%~nx0"
echo :ldcdStat3 >> "%temp%/%~nx0"
echo set end4a=%%arg:%winver%=%%>> "%temp%/%~nx0"
echo goto ldcdStat4 >> "%temp%/%~nx0"
rem notepad "%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
)
echo clear OK!
goto :EOF
:enover
echo could not get windows version, abort!
goto :EOF
:enosxs
echo not found %SystemRoot%/winsxs! maybe no privilege or lower windows!
echo only 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
set d_name=%1
rem 檢查參數(shù)是否匹配 %winver%, 先跳過(guò)前兩個(gè).同時(shí)準(zhǔn)備組合新版本匹配名稱,nv1存當(dāng)前版本,nv2存當(dāng)前的前一個(gè)版本
set nv1=%2_%3_
set nv2=%2_%3_
:ldcdCycle
if "%4" == "" goto :EOF
rem 檢查是否 ver_prefix 開(kāi)頭,如果是則繼續(xù)檢查是否winver,如果不是winver則表示目標(biāo)存在
set arg=%4
rem set line=set end4=%%arg:%ver_prefix%=%%
rem %line%
goto ldcdStat1
:ldcdStat2
if "%arg%" == "%end4%" goto ldcdNext
rem 檢查是否 winver 開(kāi)頭
rem set line=set end4a=%%arg:%winver%=%%
rem %line%
goto ldcdStat3
:ldcdStat4
if not "%arg%" == "%end4a%" goto :EOF
rem 至此則為 ver_prefix 開(kāi)頭 且 不等于 winver 的目錄名,檢查最新版本是否存在,存在則可刪除舊的
set newfound=false
for /d %%v in ("%SystemRoot%/winsxs/%nv1%%winver%.*_%5_*") do (
if exist %%v/nul set newfound=true
)
if "%newfound%" == "true" call:fnDelDir %d_name%
goto :EOF
:ldcdNext
set nv2=%nv1%
set nv1=%nv2%%4_
shift
goto ldcdCycle
: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
代碼導(dǎo)讀有助于大家理解程序和算法,但是基本的批處理語(yǔ)法就不講了,有幾年編程經(jīng)驗(yàn)的我想也看得懂。以下是大致幾個(gè)要注意的地方:
代碼的開(kāi)頭部分是用ver命令獲取系統(tǒng)的版本號(hào),并且存放到%winver%變量中,比如我的ver命令返回就是“Microsoft Windows [版本 6.0.6002]”,為了獲取這個(gè)“6.0.6002”,所以要做一些處理,另外,%ver_prefix%中存放的是類(lèi)似“6.0.600”,為了比較舊版本號(hào)用途。
因?yàn)榕幚頍o(wú)法實(shí)現(xiàn)嵌套嵌入功能,比如我想把從目錄中分解出來(lái)的6.0.6000.16386和%ver_prefix%進(jìn)行比較,就無(wú)法實(shí)現(xiàn)了,只好用代碼生成大法來(lái)處理,在18~24行就是生成代碼,該代碼在63行和69行調(diào)用。26行負(fù)責(zé)把控制轉(zhuǎn)移到新生成的文件中執(zhí)行。
因?yàn)閣insxs目錄是有特殊權(quán)限的,所以先用takeown命令設(shè)置當(dāng)前用戶為擁有者,然后用cacls修改目錄權(quán)限,最后用move指令將目錄轉(zhuǎn)移到winsxs_del目錄中。如果出現(xiàn)程序無(wú)法運(yùn)行的情況,請(qǐng)手工移動(dòng)回去即可。
***
.NET框架解決DLL Hell問(wèn)題:?jiǎn)栴}描述 :
***
從客戶的角度,最常見(jiàn)的版本問(wèn)題就是我們所說(shuō)的 DLL Hell 問(wèn)題。簡(jiǎn)單地講, DLL Hell 是指當(dāng)多個(gè)應(yīng)用程序試圖共享一個(gè)公用組件(如某個(gè)動(dòng)態(tài)連接庫(kù)(DLL)或某個(gè)組件對(duì)象模型(COM)類(lèi))時(shí)所引發(fā)的一系列問(wèn)題。最典型的情況是,某個(gè)應(yīng)用程序?qū)⒁惭b一個(gè)新版本的共享組件,而該組件與機(jī)器上的現(xiàn)有版本不向后兼容。雖然剛安裝的應(yīng)用程序運(yùn)行正常,但原來(lái)依賴前一版本共享組件的應(yīng)用程序也許已無(wú)法再工作。在某些情況下,問(wèn)題的起因更加難以預(yù)料。比如,當(dāng)用戶瀏覽某些 Web 站點(diǎn)時(shí)會(huì)同時(shí)下載某個(gè) Microsoft ActiveX? 控件。如果下載該控件,它將替換機(jī)器上原有的任何版本的控件。如果機(jī)器上的某個(gè)應(yīng)用程序恰好使用該控件,則很可能也會(huì)停止工作。
在許多情況下,用戶需要很長(zhǎng)時(shí)間才會(huì)發(fā)現(xiàn)應(yīng)用程序已停止工作。結(jié)果往往很難記起是何時(shí)的機(jī)器變化影響到了該應(yīng)用程序。用戶可能會(huì)回憶起一周前安裝了一些東西,但安裝與目前看到的狀態(tài)并沒(méi)有任何明顯的關(guān)聯(lián)。 更糟的是,現(xiàn)在很少有診斷工具幫助用戶(或幫助他們的技術(shù)支持人員)確定有什么問(wèn)題。
這些問(wèn)題的原因是應(yīng)用程序不同組件的版本信息沒(méi)有由系統(tǒng)記錄或加強(qiáng)。而且,系統(tǒng)為某個(gè)應(yīng)用程序所做的改變會(huì)影響機(jī)器上的所有應(yīng)用程序—現(xiàn)在建立完全從變化中隔離出來(lái)的應(yīng)用程序并不容易。
很難建立一個(gè)隔離應(yīng)用程序的一個(gè)原因是當(dāng)前運(yùn)行時(shí)環(huán)境只允許單獨(dú)版本組件或應(yīng)用程序的安裝。這個(gè)限制意味著組件的編寫(xiě)者必須以向后兼容的方式編寫(xiě)他們的代碼,否則當(dāng)他們安裝新組件的時(shí)候會(huì)有終止已有應(yīng)用程序的風(fēng)險(xiǎn)。實(shí)際上,如果可能的話,編寫(xiě)永遠(yuǎn)向后兼容的代碼是非常難的。在 .NET 中,side by side 概念是版本問(wèn)題的核心。"Side by side" 是在同一臺(tái)機(jī)器上同時(shí)運(yùn)行不同版本的相同組件的能力。使用支持并列的組件,編程人員不必努力維護(hù)嚴(yán)格的向后兼容,因?yàn)椴煌膽?yīng)用程序自由使用某個(gè)共享組件的不同版本。
.NET框架與DLL Hell問(wèn)題:發(fā)布和安裝
現(xiàn)在安裝應(yīng)用程序是多步過(guò)程。一般,安裝一個(gè)應(yīng)用程序包括復(fù)制許多軟件組件到磁盤(pán),和在系統(tǒng)中進(jìn)行一系列描述那些組件的注冊(cè)項(xiàng)。
注冊(cè)表中的項(xiàng)和磁盤(pán)上文件的分隔使復(fù)制應(yīng)用程序和卸載他們非常困難。而且,在注冊(cè)表中完全描述某個(gè) COM 類(lèi)所需的許多項(xiàng)之間關(guān)系非常松散。這些項(xiàng)常常包括聯(lián)合類(lèi)、接口、類(lèi)型庫(kù)和 DCOM app ID 的項(xiàng),不涉及任何放在注冊(cè)表文檔擴(kuò)展或組件類(lèi)別的項(xiàng)。要時(shí)常手工保持這些項(xiàng)的同步。
最后,需要該注冊(cè)足跡激活任何 COM 類(lèi)。這極大地復(fù)雜了發(fā)布分布式應(yīng)用程序的過(guò)程,因?yàn)楸仨毜矫總€(gè)客戶端的機(jī)器進(jìn)行適當(dāng)?shù)淖?cè)項(xiàng)。
如今另一個(gè)共同問(wèn)題是:對(duì)一個(gè)正在運(yùn)行的應(yīng)用程序進(jìn)行更新是不現(xiàn)實(shí)的。這是 Web 應(yīng)用程序最大的問(wèn)題,Web 應(yīng)用程序必須停止工作然后重啟動(dòng)以更新應(yīng)用程序使用的 COM 類(lèi)。
這些問(wèn)題主要由從組件自己分離傳來(lái)的組件描述引起的。換句話說(shuō),應(yīng)用程序不是自描述的和獨(dú)立的。
以上就對(duì)需要.NET框架解決的DLL Hell問(wèn)題進(jìn)行了簡(jiǎn)單的描述。
聯(lián)系客服