精华内容
参与话题
问答
  • c盘windows文件夹太大,installer文件夹太大

    万次阅读 多人点赞 2016-04-21 16:10:15
    如上图所示,C盘中windows文件夹占用了35.5G空间,仔细查了一下,windows文件夹中的installer文件夹又占用了22.1G空间。 网上找了很多资料,也去微软的社区看了,有许多人都有遇到这个问题,就说了installer里面的...

    新安装的系统,过了不久,突然发现50G的C盘只剩5G的空间了,又过了几天,只剩2G了,简直无下限啊!

    如上图所示,C盘中windows文件夹占用了35.5G空间,仔细查了一下,windows文件夹中的installer文件夹又占用了22.1G空间。

    网上找了很多资料,也去微软的社区看了,有许多人都有遇到这个问题,就说了installer里面的东西不能乱删,但都没有给出一套完成的解决方法。这里我整理了一下我查到的资料,其实很简单:

    1、下载WICleanup

    2、解压缩后看到有如下图内容。


    3、快捷键windows+R,输入cmd,点击“确定”,打开cmd,如下图。


    4、WICleanup解压缩后文件夹目录为 E:\迅雷下载\wicleanup,分别执行如下两条命令:

    cd /d E:\迅雷下载\wicleanup,进入wicleanup 文件夹;

    WICleanupC.exe -s 执行工具,清理installer文件夹。

    如下图:


    一切OK了,我清理后到目前几天时间,电脑没出什么异常。

    展开全文
  • windows installer正准备安装

    万次阅读 2018-05-07 21:12:00
    打开某软件时,电脑一直提示“windows installer正准备安装”,然后一直自己安装,烦的要死。后来终于各种查找解决。解决方案:1、浏览器搜索“windows install clean up”,在相关网站找到这款软件,然后将软件...
    

    打开某软件时,电脑一直提示“windows installer正准备安装”,然后一直自己安装,烦的要死。后来终于各种查找解决。

    解决方案:

    1、浏览器搜索“windows install clean up”,在相关网站找到这款软件,然后将软件下载安装

    2、软件安装完成之后,在电脑程序里面找到“windows install clean up”启动该软件,启动软件后,在软件里面找到“对应的程序”,然后清除该安装程序即可

    出现问题原因:因为windows installer 安装软件是windows电脑系统通用的一种软件安装方式,但windows installer 本身是存在缺陷,就是电脑软件多册删除之后,会导致windows installer 出错,就是无论运行任何软件,都出弹出“windows installer正准备安装..............”情况。

    而安装“windows install clean up”后,它会列出目前系统中所有使用Windows Installer安装的软件,选中出问题的软件,然后点“Remove”按钮即可。

    3、最后打开WPS等软件时就不会出现问题了。、

    参考网址:https://jingyan.baidu.com/article/bea41d4385ddcfb4c41be65e.html

    展开全文
  • installer

    2017-10-13 10:32:00
    if (args.Length == 0) { ServiceBase[] ServicesToRun; ServicesToRun = new ServiceBase[] { new MyService1() }; ServiceBase.Run(ServicesToRun);...
    
            if (args.Length == 0)
            {
                ServiceBase[] ServicesToRun;
                ServicesToRun = new ServiceBase[] { new MyService1() };
                ServiceBase.Run(ServicesToRun);
            }
            else if (args[0].ToLower() == "/i" || args[0].ToLower() == "-i")
            {
                try
                {
                    string[] cmdline = { };
                    string serviceFileName = System.Reflection.Assembly.GetExecutingAssembly().Location;
    
                    TransactedInstaller transactedInstaller = new TransactedInstaller();
                    AssemblyInstaller assemblyInstaller = new AssemblyInstaller(serviceFileName, cmdline);
                    transactedInstaller.Installers.Add(assemblyInstaller);
                    transactedInstaller.Install(new System.Collections.Hashtable());
                }
                catch (Exception ex)
                {
                    string msg = ex.Message;
                }
            }
            else if (args[0].ToLower() == "/u" || args[0].ToLower() == "-u")
            {
                try
                {
                    string[] cmdline = { };
                    string serviceFileName = System.Reflection.Assembly.GetExecutingAssembly().Location;
    
                    TransactedInstaller transactedInstaller = new TransactedInstaller();
                    AssemblyInstaller assemblyInstaller = new AssemblyInstaller(serviceFileName, cmdline);
                    transactedInstaller.Installers.Add(assemblyInstaller);
                    transactedInstaller.Uninstall(null);
                }
                catch (Exception ex)
                {
                    string msg = ex.Message;
                }
            }
    

      

    转载于:https://www.cnblogs.com/xiangxiong/p/7659880.html

    展开全文
  • 找出占用Installer 目录空间的元凶

    千次阅读 2018-05-17 15:52:00
    找出占用Installer 目录空间的元凶 为什么谈这个话题 今天看到一台windows 7 的计算机,C盘分了50GB,结果installer 目录有47GB,幸亏我对该目录启用过压缩,压缩后实际占用32GB的样子,但也足够大了,已经导致C...

    找出占用Installer 目录空间的元凶

    为什么谈这个话题

    今天看到一台windows 7 的计算机,C盘分了50GB,结果installer 目录有47GB,幸亏我对该目录启用过压缩,压缩后实际占用32GB的样子,但也足够大了,已经导致C盘满了,我删了下TEMP目录,清了c:\users\下一些很久没用的用户配置文件,救回2GB出来。但这个Installer目录占用这么多空间也得调查下是什么原因,找到方法可以缩减。

    一些其他的尝试

    列举下一些之前尝试的方法,这些方法安全,但是收效甚微。

    • windows清理程序,即使使用了隐藏的高级功能,但是清理掉的空间不是很多。cmd.exe /c Cleanmgr /sageset:65535 /sagerun:65535 sageset会弹出窗口让选择清理的项目,选择后会保留在注册表中,后面sagerun就会使用这个注册表里存储的选项执行静默的清理。
    • ntfs压缩installer 目录。文章开头已经说了,47GB,压缩到32GB,虽然压缩比率也算较大了,但是其实并没有解决回答为什么增长这么大的问题,其实我觉得应该有办法可以清理。只是不好操作而已,一旦我们必要的信息收集的差不多了,清理这个操作虽然危险,但是应该是可以做的。

    不靠谱的清理软件

    OK,一般这种状况下会找些流行的专用软件来干这个事,毕竟术业有专攻,然后桌面祭出了WICleanup,说他用这个软件清理过,还可以,主要问题是UI上没有提供全选,所以使用很麻烦。

    我说我看看,看UI上列出了冗余文件,而且我的文件清单上有多个文件大小都是一个尺寸,我说这个软件难道是可以算出重复文件的功能,然后把重复文件删掉?!,然后鉴于桌面说用过,我觉得应该至少问题不大吧,看了下目录下有个命令行的版本带-s 可以静默清理,我试了一下,发现清掉30GB多的空间,到installer 目录一看,我就知道坏了,里面的MSP、MSI文件全干掉了。https://img-blog.csdn.net/20180517153642680?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3lva2U4OA==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70)

    这个软件我后面看开发时间也是超级古老了,最近还有人发Blog介绍这个工具,而且评论区还有好多人反馈清理了好多………….没发现副作用很大么?。

    
    pjl6523853
    爱武侠的程序员2018-04-09 20:37:08#4楼
    太感谢博主了!帮我清理了30G!请问博主可以转载嘛
    
    Maxwell_STU
    Maxwell_STU2018-03-11 00:45:01#3楼
    感谢博主分享,突然就清理出来10G以上的空间,感觉清爽了超级多,压力一下子就小了。
    
    KEVIN_LI_MY
    KEVIN_LI_MY2017-11-29 08:59:26#2楼
    我清理出了3g,也不少了。
    

    我稍后测试了下用Wicleanup清理过的计算机,控制面板中部分程序的卸载、修复,windows 更新均有问题,主要问题是弹对话框提示找文件。

    不靠谱的文档指引

    一篇看起很高深的文章指引,又是解构msi文件,又是C++清注册表,主要是一个操作,就是删除HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Installer\Products\***********\Patches注册表,然后一股脑删installer目录的下的MSP、MSI文件。

    • 删Patch 注册表这事,会导致系统里对历史更新的记录不存在。在更新软件时会直接安装新软件进行覆盖,而不会清理历史版本,这样可能因为残留导致问题。
    • 第三方软件也放MSP、MSI文件在这个目录,但是产品注册表不一定老老实实的写在上面那个位置,比如Adobe。
    • 还被系统正常使用的MSP、MSI等文件不应当被删除(且看后面的软件如何确认孤立的安装文件,应该有区分的清理,而不是一股脑全删)。

    一个看起来可能还靠谱的软件patchCleaner

    有了上面教训,我想我得了解下此类软件的原理,然后确定可行后才能使用。首先我参考了微软的员工的解决方法,算是廖胜于无吧,大概意思就是官方仅支持通过卸载软件的方式来清理installer目录,这个Blog在评论区讨论了很多次,但似乎没有什么好的结论,也没有提供太多有价值的信息。

    在我访问类似superuser 上的讨论时,我发现了这个软件patchCleaner,为啥说可能还靠谱,因为下面:

    • 最近更新时间 3/03/2016,相对较新
    • 有官方网站还可以访问
    • 有FAQ,还在sourceforge上有个portable版本,尽管我还是没有找到源码。
    • 有原理解释,它说使用WMI来查询程序产品的信息,然后匹对installer 目录下的文件,清理没有在WMI中登记的信息(实际发现应该是用windows installer 的COM对象来查询的相关msi、msp文件的信息)。
    • 我在程序目录找到了一个WMIProducts.vbs 程序,它会使用installer的COM来列出一些程序和组件所使用的MSI、MSP信息。
    • 提供两种选项,DELETE 和MOVE,但是MOVE是推荐的操作,给用户选择且考虑了风险,所以这是我觉得靠谱的地方。我觉得可以提供第三种,COMPRESS(利用ntfs压缩技术可以节省一部分空间)或者第四种,删除前压缩文件到一个文件,这个文件可以后续用于还原。这个文件可以丢在其他地方,比如移动硬盘或者备份的地方。
    • 程序的界面还利用了一些MSI的技术可以显示MSI、MSP文件的详细信息。

    MSP信息

    准备让数据说话

    总结了上面的一些信息,我目前有下列问题,需要让实际的数据说话:

    • 登记在系统中的MSP、MSI文件和孤立的MSP、MSI文件大小汇总占的比率有多大,比如我这个47GB installer的文件夹的情况下孤立的MSP、MSI文件尺寸是什么比率?知道这个信息可以让我们确定如果我们的工具只清理孤立的MSP,MSI的话,这个工具的作用程度可能会有多大。
    • 多个这种非常大的installer 的计算机中,孤立的MSP、MSI文件尺寸是什么比率?有什么特征么? 如果孤立安装文件所占比率较大在多个计算机有共性,那么说明这种工具有普遍需求性。
    • 孤立的MSP、MSI文件的相关信息有哪些共同点,多台计算机上这些匹配出的孤立文件的相关信息有哪些共同点,比如发行者,文件版本等等。是否特定的程序造成了以上问题,如果多个计算机都因为某个软件或者更新导致Installer目录较大,那么我们是否可以通过集中的策略进行控制或者避免?

    我的计划:

    • 随机抽取一批windows 计算机,按照操作系统大版本分类。 测试验证了自己的win10
    • 使用patchCleaner提供的VBS文件,搜集多个计算机上的在WMI和MSI数据库中已经登记的MSP、MSI文件列表。 自己写了一个ps 可以统计以上信息
    • 统计每个计算机上的installer 目录下的文件、位置、尺寸,发行者、文件版本、title等信息。 大部分是微软自己的更新
    • 汇总统计每个计算机上的已登记的MSP、MSI文件的总尺寸,孤立的MSP、MSI文件的总尺寸,两者的尺寸比率分布。 个人计算机上孤立的尺寸占了总空间的一半多,而且大部分是一个KB2345678 的更新,我在已安装的更新中搜索了这个KB,发现这个更新是没有装的(这些文件的日期是2015-2017都有,这个补丁应该出来很久了)

    自己写了powershell 脚本,按照patchCleaner的思路,自己过滤出孤立的安装文件,这部分孤立文件我后来只过滤出MSI、MSP后缀的文件(这部分文件占用最大)。其他后缀的Installer目录下的文件,我们不去动它(因为可能被引用,比如ICON文件或者EXE等文件)。MSI,MSP文件当中会有一些除了发布者为微软的安装文件,比如Adobe的文件用get-msisummaryinfo 获取不到信息,我们也过滤掉(在PatchCleaner中也默认过滤掉了adobe的安装文件),过滤后的孤立安装文件大概如下图所示。

    下面截图中时我的win10 的installer目录的分析情况。使用之前,用过windows 清理程序的高级功能清过。即使使用清理程序清理过,我们也可以看见孤立的文件还有大概4GB,我手动测试了两个安装程序在清理后的工作情况,一个是AMD的显卡软件的,一个是微软的c++ 2012 redistribution ,我先把文件从installer 目录剪切走,然后执行卸载或者修复功能,都没有报错或者弹框要文件。

    件夹统计

    patchCleaner 发现的信息统计

    自己的工具?

    当上面数据很明了清晰时,我们是否可以写出自己的工具来..大致臆想了自己工具的功能和执行步骤

    • 首先使用cleanmgr 清理一次,看看用户是否还要继续。
    • 使用压缩功能,压缩一次,看看用户是否还要继续。
    • 算出孤立文件的数量(需要验证安全性),优先MOVE (注意juncpoint的兼容问题),再进行删除。我觉得删除的时候是否可以提供选项把删除的文件打包存放在其他位置,出问题时可以用来恢复。
    • 导出孤立文件列表、记录删除的孤立文件清单,用于后续分析。

    列下PatchCleaner存在的不足的地方:
    1.没有办法导出列表。
    2.需要.net framwork4,不便于携带。
    3.似乎没有办法可以对筛选后的孤立的文件再做选择性操作。

    由于windows 上有PSMSI 这个powershell 模组,所以最开始省去我大部分代码,把主要精力放在测试上(反复考虑后,还是自己写powershell 调用Installer Com 接口的函数用于获取信息,虽然比较困难,全程要用反射功能来操作Installer COM,而且读取MSP文件额度问题已经解决,读MSP时,数据库的Openmode需要指定其他值,这样可以不依赖外部模组)。

    
    $Installer = New-Object -ComObject WindowsInstaller.Installer
    $Type = $Installer.GetType()
    
    function Get-MsiProducts {
        $Products = $Type.InvokeMember('Products', "GetProperty", $null, $Installer, $null)
        foreach ($Product In $Products) {
            $hash = @{}
            $hash.ProductCode = $Product
            $Attributes = @('Language', 'ProductName', 'PackageCode', 'Transforms', 'AssignmentType', 'PackageName', 'InstalledProductName', 'VersionString', 'RegCompany', 'RegOwner', 'ProductID', 'ProductIcon', 'InstallLocation', 'InstallSource', 'InstallDate', 'Publisher', 'LocalPackage', 'HelpLink', 'HelpTelephone', 'URLInfoAbout', 'URLUpdateInfo')      
            foreach ($Attribute In $Attributes) {
                $hash."$($Attribute)" = $null
            }
            foreach ($Attribute In $Attributes) {
                try {
                    $hash."$($Attribute)" = $Type.InvokeMember('ProductInfo',"GetProperty", $null, $Installer, @($Product, $Attribute))
                } catch [System.Exception] {
                }
            }
            if($hash."LocalPackage"){
                if(test-path $hash."LocalPackage"){
                    $hash.size=$(get-item $hash."LocalPackage").Length
                }
            }
            New-Object -TypeName PSObject -Property $hash
        }
    }
    
    function Get-MsiPatch {
        [cmdletbinding()]
        param(
            $product
        )
        $Patches = $Type.InvokeMember('Patches',"GetProperty", $null, $Installer, @($product))
        foreach ($Patch In $Patches) {
            $hash = @{}
            $hash.ProductCode = $Product
            $hash.PatchCode=$Patch
            $Attributes = @('LocalPackage')        
            foreach ($Attribute In $Attributes) {
                $hash."$($Attribute)" = $null
            }
            foreach ($Attribute In $Attributes) {
                try {
                    $hash."$($Attribute)" = $Type.InvokeMember('PatchInfo', 'GetProperty', $null, $Installer, @($Patch, $Attribute))
                } catch [System.Exception] {
                    #$error[0]|format-list –force
                }
            }
            if($hash."LocalPackage"){
                if(test-path $hash."LocalPackage"){
                    $hash.size=$(get-item $hash."LocalPackage").Length
                }
            }
            New-Object -TypeName PSObject -Property $hash
        }
    }
    
    function Get-MSIFileInfo {
        [cmdletbinding()]
        param
        (
            [Parameter(Mandatory = $true)]$Path       
        )   
        try {
            if(test-path $path){
                $path=get-item $path
                $extension=$path.Extension.ToLower()
                $DBOPENMODE=0
                $TABLENAME='Property'
                if($extension -eq '.msp'){
                    $DBOPENMODE=32
                    $TABLENAME="MsiPatchMetadata"
                }
                $msiProps = @{}
                $Database = $Type.InvokeMember("OpenDatabase", "InvokeMethod", $Null, $Installer, @($Path.FullName, $DBOPENMODE))
                $Query = "SELECT Property,Value FROM $TABLENAME"
                $View = $Database.GetType().InvokeMember("OpenView", "InvokeMethod", $null, $Database, ($Query))
                $View.GetType().InvokeMember("Execute", "InvokeMethod", $null, $View, $null)|Out-Null
                $record=$view.gettype().invokemember("Fetch","InvokeMethod",$null,$view,$null)   
                # Loop thru the table
                while($record -ne $null) {
                    $propName=$null
                    $propValue=$null
                    $propName=$record.gettype().invokeMember("StringData","GetProperty",$null,$record,1)
                    $propValue= $record.gettype().invokeMember("StringData","GetProperty",$null,$record,2)
                    $msiProps[$propName] =$propValue
                    $record=$view.gettype().invokemember("Fetch","InvokeMethod",$null,$view,$null)
                }
                $view.gettype().invokemember("Close","InvokeMethod",$null,$view,$null)|Out-Null
                # Compose a unified object to express the MSI and MSP information
                # MSP  'DisplayName','ManufacturerName','Description', 'MoreInfoURL','TargetProductName'
                # MSI 'ProductName','Manufacturer','ProductVersion','ProductCode','UpgradeCode'
                if($extension -eq '.msi'){
                    New-Object  -TypeName PSObject -Property @{
                        'DisplayName'=$msiProps['ProductName']
                        'Manufacturer'=$msiProps['Manufacturer']
                        'Version'=$msiProps['ProductVersion']
                        'PackageCode'=$msiProps['ProductCode']
                        'Description'=$msiProps['Description']
                        'TargetProductName'=$msiProps['TargetProductName']
                        'MoreInfoURL'=$msiProps['MoreInfoURL']
                        'Size'=$path.Length
                        'Path'=$path.FullName
                        'CreationTime'=$path.CreationTime
                    }
                }elseif($extension -eq ".msp"){
                    New-Object  -TypeName PSObject -Property @{
                        'DisplayName'=$msiProps['DisplayName']
                        'Manufacturer'=$msiProps['ManufacturerName']
                        'Version'=$msiProps['BuildNumber']
                        'PackageCode'=$msiProps['ProductCode']
                        'Description'=$msiProps['Description']
                        'TargetProductName'=$msiProps['TargetProductName']
                        'MoreInfoURL'=$msiProps['MoreInfoURL']
                        'Size'=$path.Length
                        'Path'=$path.FullName
                        'CreationTime'=$path.CreationTime
                    }
                }       
            }     
        } catch {
            Write-Error $_.Exception.Message
        }
    }
    
    function filter_product{
        param(
            $productName
        )
    
        $PRODUCT_FILTER=@("adobe")
    
        $r=$PRODUCT_FILTER|?{$productName -like "*$_*"}
        if($r){
            return $true
        }else{
            return $false
        }
    }
    
    
    $products=Get-MsiProductinfo
    $patches=$products|%{Get-MsiPatch -product $_.ProductCode}
    $productsHash=@{}
    $products|?{$_.LocalPackage}|%{$productsHash.add($_.LocalPackage,$true)}
    $patchesHash=@{}
    $patches|?{$_.LocalPackage}|%{if(!$patchesHash.ContainsKey($_.localPackage)){$patchesHash.add($_.LocalPackage,$true)}}
    $InstallFolder="$($env:SystemRoot)\installer"
    $files=dir  -Recurse -Include "*.msi","*.msp" -path $InstallFolder
    $Files2=$files|%{
        if($productsHash.ContainsKey($_.FullName)){
            $_|Add-Member -MemberType NoteProperty -Name "installerState" -Value "InstalledProduct"          
        }elseif($patchesHash.ContainsKey($_.FullName)){
            $_|Add-Member -MemberType NoteProperty -Name "installerState" -Value "InstalledPatch"
        }else{
            $_|Add-Member -MemberType NoteProperty -Name "installerState" -Value "Orphaned"
        }
        $_
    }
    
    $groups=$files2|Group-Object -Property "installerState"
    $groups|%{
        @{$($_.name)=($_.group|Measure-Object -Property Length -Sum).Sum}
    }
    $OrphanedFiles=$($groups|?{$_.name -eq 'Orphaned'}).Group
    if($OrphanedFiles){
        $ValidOrphanedFiles=($OrphanedFiles|%{
            $item=Get-MSIFileInfo -path $_.FullName;
            if((filter_product $item.DisplayName) -or (filter_product $item.Manufacturer)){
                # do nothing for this filtered products
            }else{
                $item
            }
        })
        $selectedOrphanedFiles=$ValidOrphanedFiles|select DisplayName,Manufacturer,Size,Path,CreationTime|Out-GridView -PassThru -Title "select the Orphaned Files to delete"
        if($ValidOrphanedFiles){
            $ValidOrphanedFiles|Export-Csv -Path $PSScriptRoot\ValidOrphanedFiles.$((get-date).ToString('yyyyMMddhhmmss')).csv -NoClobber -NoTypeInformation -Encoding UTF8
        }
        if($selectedOrphanedFiles){
            $selectedOrphanedFiles|Export-Csv -Path $PSScriptRoot\CleanedOrphanedFiles.$((get-date).ToString('yyyyMMddhhmmss')).csv -NoClobber -NoTypeInformation -Encoding UTF8
            # delete code
            #$selectedOrphanedFiles|remove-item -Force
        }
    } 
    
    

    需要进一步深挖

    使用上面的powershell 脚本在另外一台计算机运行,发现输出如下图,大部分是office的更新,还有4个关于7zip的,所以我又瞄了一眼添加删除程序里的信息。

    7z

    7z 在添加删除里显示占用空间1.91GB。有点奇怪,我找到这篇参考 还有这篇blog,让我们找找7zip的注册表设置。

    7zip size

    ######### 我们需要看看HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Uninstall\[IdentifyingNumber]\EstimatedSize
    ######### 通过win32_product 可以获取程序的IdentifyingNumber
    Caption           : 7-Zip 9.20 (x64 edition)
    Description       : 7-Zip 9.20 (x64 edition)
    HelpLink          : http://www.7-zip.org/support.html
    HelpTelephone     :
    IdentifyingNumber : {23170F69-40C1-2702-0920-000001000000}
    InstallDate       : 20180516
    InstallDate2      :
    InstallLocation   :
    InstallSource     : C:\Windows\ccmcache\7\
    Language          : 1033
    LocalPackage      : C:\Windows\Installer\623473.msi
    PackageCache      : C:\Windows\Installer\623473.msi
    PackageCode       : {23170F69-40C1-2702-0920-000002000000}
    PackageName       : 7z920-x64.msi
    

    然后我们发现7zip的EstimatedSize为2004912,而symantec的EstimatedSize为608916

    
    ####### 发现7zip 应该是在注册表中写错数值了,可能是对EstimatedSize单位理解不对,正确单位是1kb的单位。
    PS E:\> 594mb/608916
    1022.89009321483
    PS E:\> 2004912kb/1gb
    1.91203308105469
    PS E:\> 608916kb/1mb
    594.64453125
    PS E:\>
    

    原来7Z只是软件BUG导致的尺寸显示问题,那我们接着查补丁相关的问题。

    然后我们对孤立的安装文件按照尺寸排序,看看这些文件的详细内容。PSMSI模组的get-msisummaryinfo 工作似乎不是很好,所以我们看不到msp的详细信息(比如我关注的KB编号),没有关系,我们有专门工具Orca可以看MSI、MSP的信息。
    这里写图片描述

    以dbeb3e.msp 为例,我们看看orca的显示,切到msipatchMetadata表,这个补丁的KB编号为KB4011169

    这里写图片描述

    让我们看看这个KB编号的补丁打了没有,在已安装的更新中搜索这个KB编号,没有找到。

    该补丁对应的ProductID 是{643AA346-D215-46E8-89B5-152AD0B7034E},在目标计算机的注册表中搜索这个ProductID 也找不到结果。

    那么我们在WSUS看看这个KB4011169补丁的信息。

    • 补丁已经被其他更新取代,需要的计算机只有3台,然而这三台计算机并不包含我现在正在排错的这个计算机。
    • 取代此更新的补丁清单中KB4018389这台计算机上已经安装。
    • 取代KB4011169的补丁链为:
    ####### 最上面的这个补丁编号是最新的取代该补丁的补丁编号,这个补丁对我这台正在排错的计算机已经安装。
    Kb4018389
    KB4018330
    Kb4018297
    KB4011690
    Kb4011636
    Kb4011279
    Kb4011229

    这里写图片描述

    这里我找到一个方法可以方便的批量看MSP的信息,而不用图形的Orca 工具。下面脚本遍历所有MSP文件,然后提取MsiPatchMetadata中的Displayname属性(包含微软补丁的KB编号)

    
    $msps=dir -recurse -path c:\windows\instaler\ -include *.msp 
    $xxx=$msps|%{
        $displayname=Get-MSITable -Path $_.fullname -Table MsiPatchMetadata|?{$_.property -eq 'displayname'}|Select-Object -ExpandProperty "value"; 
        [PSCustomObject]@{"displayname"=$displayname;Path=$_.fullname}
    }
    
    $xxx|out-gridview
    

    然后在窗口里搜索以上列的取代KB4011169的补丁链KB编号,发现每个历史补丁都在。

    这里假设下孤立安装文件产生的主要原因是因为补丁取代导致,那我们验证下这个测试:

    1. 把KB4011169的对应的孤立文件dbeb3e.msp 移走,然后因为取代该补丁的最新补丁KB为Kb4018389,且在正在排错的这个计算机上有安装。那我们测试卸载这个Kb4018389补丁,看是否有问题。没有问题,因为这个补丁是补丁替代链上的最后一个补丁

    2. 卸载KB4018389后,其替代的补丁KB4018330是否会在已安装的更新列表中呢?(windows 是否会还原上一个版本的补丁?)是的,第一次卸载这个补丁花了4-5小时,重启后发现前一个版本的补丁在已安装的更新中。

    3. 如果我们卸载了KB4018389,那么对应Kb4018389现在对应的MSP文件,c:\windows\installer\dd988e.msp 是否会被删掉?是的,该文件在补丁卸载后在installer目录不再存在。

    4. 假设卸载了KB4018389,我们又通过运行windows更新又把它更新上了,那么新安装的KB4018389对应的MSP文件名字是否有变化?名字有变化,变为dc993.msp

    5. 把KB4018389(kb4011196对应的最新补丁)的前一个版本补丁(KB4018330)对应的安装文件ddf836.msp 删除,那我们测试卸载这个Kb4018389补丁,看是否有问题。同时注意KB4018330或Kb4018297是否会出现在已安装更新里。 KB4018389 可以正常卸载没有问题,KB4018330由于我们把其对应的补丁的MSP文件移走所以在已安装的更新中看不到。但是我看到了KB4018297在已安装的更新当中,有意思的发现。另外这个是否如果检查更新的话,你会看到有个两个更新可用(KB4018389,KB4018330)看来我得加一个测试

    6. 使用脚本删除找出的所有孤立的MSP、MSI文件,然后卸载KB4018297,看看是否报错?(这个时候应该没有任何历史版本可以用了),另外卸载后检查更新看看更新会检查到几个?(涉及到历史补丁在WSUS的维护工作)。 卸载不会报错,检查更新后发现有三个补丁,KB4018389,KB4018330 同时存在,我选择更新KB4018389和另外一个,看看重启后是否还有让更新KB4018330,重启后发现不再提示KB4018330的更新

    写在最后

    • 我想已经有足够的信息去弄明白为什么Installer目录会变得这么大了,因为windows 保留了多个补丁的历史替代版本,当你卸载一个补丁A时,它还原上一个版本的补丁B,如果这个B还有上一个版本C,当你再卸载B时,它会还原C。

    • 系统应该有信息保留着补丁链的信息,因此如果找到这些信息的存放位置,可以构建一个工具来保留特定数目的补丁链,比如只保留一个历史版本。

    • 按照现有的计算机的情况分析,instaler的空间大部分是被windows的 更新所占用,特别是补丁有多个替代版本时。其中office 补丁最多。

    • Windows Disk Cleaner 有清理历史补丁的功能,但是不确定它的逻辑,比如我自己的windows 10 机器,使用了磁盘清理功能后,还有较多的历史补丁存在。如果要弄明白windows disk cleaner的机制,可能还要做很多的实验才有结果。

    • powershell 使用的PSMSI的cmdlet get-msisummaryinfo 感觉在不同操作系统上显示的信息不同,不是太可靠。所以自己最后决定还是写powershell 函数来提取关键信息,最终完成单脚本不再使用PSMSI模组。改良后的脚本最后发现了大量的SilverLight 更新残留包,占了大概12GB,因为之前使用的get-msiSummaryinfo 获取silverlight 相关补丁信息时,获取不到标题。所以会被认为是adobe的包跳过。

    展开全文
  • installer_r24.4.1-windows.part3.rar
  • 1.安装打包插件:Microsoft Visual Studio 2017安装程序项目 2.联机查找下面的组件,然后安装,重启VS,进行插件安装 3.新建安装项目,另外,有些人可能会想这么多安装类型,怎么选。因为我们这里说的Windows...
  • 安装好jdk后CMD模式无法显示java 更改Path路径为绝对路径
  • C:\WINDOWS\Installer文件夹的安全清理

    千次阅读 2017-04-05 10:33:54
    作者:eygle |English 【转载时请标明出处和作者信息】|【恩...这几天微软发布了不少补丁,系统C:\)又开始空间告警。 没办法又要研究一下哪些空间是可以释放的,我的C:\分配了10G的空间,一度又一度的空间紧
  • Advanced Installer打包Winform后安装在C盘权限不足的解决方法 开发环境:VS2012 运行环境:Win7+ 问题描述:Advanced Installer是一个使用起来很方便的打包工具,但是最近打包后在Win7及以后的系统上安装(默认C盘...
  • 清理C盘windows下的installer,清理C盘windows下的DriverStore,迁移android stdio 的模拟器avd的存放路径
  • C盘清理/瘦身

    千次阅读 多人点赞 2017-11-26 14:54:16
    自windows升级、打补丁等多番操作以来,很多用户C盘空间锐减,本文介绍笔者上次成功清出20G+空间的经验,希望对大家有所帮助。1、打开此电脑->C盘属性->磁盘清理-> 清理系统文件(或Win+R 运行...
  • 详见... (注意:若Windows自动更新之后导致Windows installer文件路径找不到,可以在磁盘管理中,重新把installer的虚拟映射到C:\Windows installer)   在
  • 今天在用Universal_USB_Installer制作Ubuntu系统的U盘启动时,发现了这样的问题: 如图,第四步那里选定了特定的Persistent file size,这个本来是为了让你选择合适的大小来保存自己的修改数据的(比如选择了5...
  • 最近我的笔记本C盘见红,可用空间就剩3G了,在网上查询的清理C盘的方法都试验了,但是可用空间始终升不上来,后来逐个排查,发现C盘中的Windows文件夹很大,大概40G了。。。这个文件夹下最大的是一个叫做installer的...
  • Windows Installer 5.0.810.500.rar

    千次下载 热门讨论 2012-12-22 13:38:37
    Windows Installer 5.0.810.500.rar 解决Win7 无法访问Windows Installer服务。Windows Installer没有正确安装时可能发生这种情况...
  • MYSQL官方提供了Installer方式安装MYSQL服务以及其他组件,使的Windows下安装,卸载,配置MYSQL变得特别简单。 1. 安装准备 1.1 准备MySQL安装包 百度云盘共享链接:...
  • 然鹅,C盘的所有者默认为:TrustedInstaller ,变更administratos后无法保存,然后就各种度娘,然鹅什么注册表,组策略,用户设置,都不启个鸟用,无奈,将所有账户禁用掉了,想要看一下是否还可以使用,然而所有...
  • Windows Installer 冗余文件清理工具 v3.1.0.180 绿色版,本软件用于清理C盘installer文件夹内冗余文件,实测有效,一次性可以清理C盘10G以上垃圾文件.压缩内说明书.
  • Windows Installer 常见问题

    千次阅读 2008-04-24 15:55:00
    常见问题问: Windows Installer是一种什么样的产品? 答: Windows Installer是一种系统服务,用来安装和管理系统中的应用程序。它为应用程序的开发、定制、安装和升级提供了一种标准化的方法和手段。 问: ...
  • 在本系列上一篇文章Android包管理机制(一)PackageInstaller的初始化中我们学习了PackageInstaller是如何初始化的,这一篇文章我们接着学习PackageInstaller是如何安装APK的。本系列文章的源码基于Android8.0。 ...
  • 链接:...Installer 类 提供自定义安装的基础。 命名空间: System.Configuration.Install 程序集: System.Configuration.Install(Sy
  • 《Qt5+安装包制作(Qt Installer Framework)》

    万次阅读 热门讨论 2018-11-07 15:52:56
    Qt Installer Framework 概述 Qt5可以使用官方的Qt Installer Framework框架制作安装包 Qt Installer Framework框架提供了一组工具和实用程序,用于创建一次安装程序,并在所有受支持的桌面Qt平台上部署它们,而...
  • 无法访问windows installer服务

    千次阅读 2016-12-27 00:24:51
    无法访问windows installer服务
  • Microsoft Visual Studio 2017 找不到 Visual Studio Installer ? 打开vs2017 ,选择 工具 --> 扩展和更新 --> 联机,搜索: Microsoft Visual Studio 2017 Installer Projects 安装。安装好以后,重启vs2017。 OK...
  • 有时候改动了Windows某些文件的所有者权限想恢复TrustedInstaller权限,但这个权限经常检查名称失败,需要注意的有两点: 1、TrustedInstaller权限的全名为: NT SERVICE\TrustedInstaller 输入时要完整输入,而且不...
  • Visual Studio 2015 Installer

    2018-09-19 13:30:35
    vs2015社区版不能打包程序,需要安装此插件,可以实现打包exe功能
  • 深入理解 OUI(Oracle Universal Installer)

    万次阅读 2011-10-24 20:11:25
    原文连接:http://www.oracledatabase12g.com/archives/%E6%B7%B1%E5%85%A5%E7%90%86%E8%A7%A3oracle-universal-installer-oui-text.html一.OUI 说明1.1.什么是 OUI(1)基于Java的图形用户界面(GUI)应用程序(2)会...
  • 症状当您首次尝试安装 Microsoft Office 程序或运行某个 Office 程序时,可能收到一条错误消息。如果您是通过 Administrator 用户帐户登录计算机的,可能收到下面的错误消息:安装时发生严重错误如果您是通过具有...
  • 前言 包管理机制是Android中的重要机制,是应用开发和系统开发需要掌握的知识点之一。 包指的是Apk、jar和so文件等等,它们被加载到Android内存中,由一个包转变成可执行的代码,这就需要一个机制来进行包的加载、...
  • 今天的主角NT6 HDD Installer 就能魔法般地帮你实现仅通过本机硬盘就能进行重装系统。 NT6 HDD Installer 是一款免费实用的 Windows 硬盘重装工具,可以支持在WinPE、XP到 Windows8 等几乎全部的系统上重新安装...

空空如也

1 2 3 4 5 ... 20
收藏数 1,083,730
精华内容 433,492
关键字:

installer