- 积分
- 1158
- 最后登录
- 2018-7-12
- 精华
- 0
- 阅读权限
- 40
- 主题
- 105
- UID
- 2512723
- 帖子
- 2894
- PB币
- 9010
- 威望
- 0
- 贡献
- 0
- 技术
- 307
- 活跃
- 2377
- UID
- 2512723
- 帖子
- 2894
- PB币
- 9010
- 贡献
- 0
- 技术
- 307
- 活跃
- 2377
|
本帖最后由 zifeityzyicq 于 2013-11-20 12:05 编辑
你有没有发现C:\Windows\Installer这个文件夹下有很多msp文件,当然前提是你安装有Office等软件,而且安装了最新的补丁。
msp是一个二进制补丁文件,按照道理在安装更新后就就可以删除了,但是真的可以直接删除么?我们一起通过解包msi来得到答案。
温馨提示:本文给跟我一样的强迫症患者观看,如果你觉得你的系统盘有N个TB,完全不需要清理,那么请你离开,安安静静的看别的帖子,谢谢配合~~
msp文件占据了C:\Windows\Installer 目录很大的空间,但是。。。他们是不能直接删除的,直接删除那你就悲剧了,日后肯定N多更新无法安装
但是天无绝人之路,方法还是有的!可以实现彻底删除msp文件,而且不影响你安装以后的Office NET等补丁(温馨提示,删除后你将无法卸载对应的更新)
原理详解
一个可靠的方案必然有实现的原理,完成这个实验你需要准备一具”尸体“(一个msi文件),还有二把手术刀(7zip与ContextConsole Shell Extension)
7zip 我想不解释了,是世界上最强大的压缩软件之一,也是本人的最爱,大家应该也听说过
ContextConsole Shell Extension 基于Installer SDK开发的msi编辑工具,有了它我们就可以看到更多msi文件的内部信息
ContextConsole Shell Extension 打开一个msi文件转到Tables 的Binary
UpdateInfo以及UnblockAll了么?他们是安装更新的关键所在!
用7zip打开对应的msi文件,找到Binary.UpdatesInfo然后解压出来,并且改名成UpdatesInfo.vbs
然后用记事本打开这个vbs文件
在这里有一条非常重要的信息
- if(OldUpdsExists=ture) Then
- //***********************
- End If
复制代码
他的意思是如果 OldUpdsExists 为逻辑真 那么 *********************
看OldUpdsExists 的名字,我们可以猜测,他是判断旧的更新存在 的一个布尔值
OK,我们再来看看OldUpdsExists 到底是什么!
我们可以发现上一句
- OldUpdsExists=CheckIfKeyExists(HKCRProKey & ProduciCode &"\Patches\Patches")
复制代码
CheckIfKeyExists,意思其实很明白,检查对应的注册表是否存在!!而参数就是一个注册表路径
接下来我们来确定 HKCRProKey 以及 ProduciCode 这二个变量是什么,我可以可以猜测到他应该是注册表的路径
来吧在往上看就有了
- Const HKCRProKey =”HKLM\SOFTWARE\Classed\Installer\Products\“
- Const ProductCode="DC3BF90CC0D3D2F398A9A6D1762F70F3"
复制代码
这下我们明白了吧,他其实就是表示HKLM\SOFTWARE\Classed\Installer\Products\DC3BF90CC0D3D2F398A9A6D1762F70F3\Patches\Patches
这个注册表路径是否存在
而他存在的时候,就会进行一系列的验证操作,如果我们我们手动他这个注册表删除,然后再把msp文件删除,那是不是就可以跳过验证,立马进入更新安装了?
OK,我们来编写一段程序,来实现我们的操作(这种繁琐的事情自然交给程序去完成)
把所有的这样注册表删除
HKLM\SOFTWARE\Classes\Installer\Products\**********\Patches
然后再删除msp文件
C++实现代码
- HKEY Products = 0, Childkey = 0;
- wchar_t ChildKeyName[MAX_PATH];
- UINT ErrorCode = 0;
- if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Classes\\Installer\\Products", 0, KEY_READ | KEY_WRITE, &Products) == 0)
- {
- //打开注册表
- for (int i = 0; RegEnumKey(Products, i, ChildKeyName, MAX_PATH) == 0
- && (ErrorCode = RegOpenKey(Products, ChildKeyName, &Childkey)) == 0; i++)
- {
- //打开子键
- //然后删除Patches
- RegDeleteKeyW(Childkey, L"Patches"); //关闭
- RegCloseKey(Childkey);
- }
- //删除所有msp文件
- wchar_t *InstallPath = ChildKeyName; //获得系统Install路径
- auto cchSystemRootStr = _tcslen(OsInfo->SystemRoot);
- memcpy(InstallPath, OsInfo->SystemRoot, cchSystemRootStr << 1); memcpy(InstallPath + cchSystemRootStr, L"\\Installer\\*.msp", (_tcslen(L"\\Installer\\*.msp") + 1) << 1);
- cchSystemRootStr += 11; WIN32_FIND_DATA FindFileData;
- auto hFileFind = FindFirstFile(InstallPath, &FindFileData); if (hFileFind != INVALID_HANDLE_VALUE)
- {
- do
- {
- //InstallPath[cchSystemRootStr] = NULL;
- memcpy(InstallPath + cchSystemRootStr, FindFileData.cFileName, (_tcslen(FindFileData.cFileName) + 1) << 1); //删除找到的msp文件 //取消只读属性
- SetFileAttributes(InstallPath, FILE_ATTRIBUTE_NORMAL); if (DeleteFile(InstallPath) == 0)
- {
- ErrorCode = GetLastError();
- } } while (FindNextFile(hFileFind, &FindFileData)); FindClose(hFileFind);
- } if (ErrorCode)
- {
- //输出错误代码
- } }
复制代码
一起来做个测试吧,安装5个Office更新,对比直接删除msp文件与删除注册表后再删除msp文件的区别
OK,我们可以看到Office更新有33个,我们选择前5个
下载完成,一共45MB更新
更新即将完成
OK 完成了
看,产生了76MB的MSP文件,我们先做个测试,直接删除这些msp文件
然后再重新检查Windows Update
发现直接删除msp后 Office只有3个了,这明显不正常,原先33个按道理安装5个后更新这么说也会有28个的样子吧,OK
我们吧删除msp文件恢复回去 再来使用我写的程序,清理注册表,然后再删除msp文件看看结果
OK,完美~~~
之后我又以每次5个Office更新为单位,还是循环 安装-清理 直到所有更新安装完成,一切正常
另外我还测试了6个可代替更新,也正常
谢谢观赏~~~~~~~~
如果你有能力,你可以自行做实验
逻辑很简单
第一步:删除所有这样的注册表 HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Installer\Products\***********\Patches
第二步:删除所有C:\Windows\Installer目录下的msp文件
另外这个特性将在下个版本的Dism管理器中实现,如果你是一名强迫症但又不会操作,你可以等待我的新版本
Dism管理器地址
https://bbs.pcbeta.com/viewthread-1423429-1-1.html
身为一名强迫症患者,大家一起来折腾吧(●'◡'●)
|
-
15
查看全部评分
-
|