44

尝试使用 WMI 获取 Windows XP 已安装程序的列表。使用 wmic,我尝试了:

wmic /output:c:\ProgramList.txt product get name,version

我得到了许多已安装程序的列表,但是在根据“添加/删除程序”显示的内容擦洗该列表后,我看到添加/删除程序的 GUI 中列出的程序比 WMI 查询中列出的程序多得多。我需要使用另一个 WMI 查询来安装其余程序吗?或者还有其他地方我需要寻找其余的地方吗?

此外,WMI 查询中列出了两个已安装的程序,它们不在“添加/删除程序”中。知道为什么吗?

4

13 回答 13

33

我相信您的语法是使用 WMI 中的Win32_Product类。一个原因是此类仅显示使用 Windows Installer 安装的产品(请参阅此处)。卸载注册表项是您最好的选择。

HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Uninstall HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall

更新评论:

卸载注册表项是列出已安装和未安装内容的标准位置。这是添加/删除程序列表将用于填充应用程序列表的位置。我确信有些应用程序没有在此位置列出自己。在这种情况下,您将不得不求助于另一种更粗略的方法,例如搜索程序文件目录或查看开始菜单程序列表。这两种方式肯定都不理想。

在我看来,查看注册表项是最好的方法。

于 2009-03-23T13:01:15.270 回答
12

所有添加/删除程序真正做的是读取这个注册表项:

HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Uninstall
于 2009-03-23T12:46:27.053 回答
7

除了最常见的已安装程序注册表项:

HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Uninstall

wmic 命令和添加/删除程序还查询另一个注册表项:

HKEY_CLASSES_ROOT\Installer\Products

列表中显示的软件名称是从名为 ProductName 的该键中的数据条目的值中读取的

从上述两个位置删除特定产品的注册表项将使其不会显示在添加/删除程序列表中。这不是卸载程序的方法,它只会从 Windows 已知的已安装软件中删除该条目。

因为,通过使用这种方法,您将失去使用添加/删除列表中的“删除”按钮从系统中彻底删除软件的机会;建议在删除注册表项之前将其导出到文件。将来,如果您决定将该项目带回列表,您只需运行您存储的注册表文件。

于 2011-02-07T16:55:09.693 回答
5

我一直在使用 Inno Setup 作为安装程序。我只使用 64 位 Windows 7。我发现正在写入注册表项

HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall

我还没有弄清楚如何让 WMI 报告这个列表(尽管该程序被列为已安装在程序和功能中)。如果我弄明白了,我会尽量记得在这里报告。

更新:

安装在 64 位计算机上的 32 位程序的条目位于该注册表位置。这里写的更多:

http://mdb-blog.blogspot.com/2010/09/c-check-if-programapplication-is.html

请参阅我在同一篇文章中描述 32 位与 64 位行为的评论:

http://mdb-blog.blogspot.com/2010/09/c-check-if-programapplication-is.html?showComment=1300402090679#c861009270784046894

不幸的是,似乎没有办法让 WMI 列出添加/删除程序列表中的所有程序(又名 Windows 7 中的程序和功能,不确定 Vista)。我当前的代码已经放弃了 WMI,转而使用注册表。查询注册表的代码本身比使用 WMI 更容易。示例代码在上面的链接中。

于 2011-03-17T02:53:51.070 回答
4

不是最好的,而是是否实用的方法:

使用HijackThis

运行 hijack this,点击“Open the Misc Tools section”按钮

HijackThis 主菜单

点击“打开卸载管理器”

劫持此配置

单击保存列表 (*.txt),提示是,记事本将打开您的添加/删除程序列表。

HijackThis 添加/删除程序管理器


来源

于 2011-04-01T05:08:30.990 回答
3

您可以使用 powershell 和批处理文件在一行中获取它:

@echo off
Powershell /command "Get-ItemProperty HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\* | Select-Object DisplayName, DisplayVersion, Publisher, InstallDate | Format-List"
Pause
于 2018-02-23T07:05:12.240 回答
2

已安装的产品由已安装的软件元素和功能组成,因此值得检查 PRODUCT 的 wmic 别名以及检查 SOFTWAREELEMENT 和 SOFTWAREFEATURE:

wmic product get name,version

wmic softwareelement get name,version

wmic softwarefeature get name,version
于 2011-03-18T05:15:52.677 回答
2

您可以使用来自http://technet.microsoft.com/en-us/library/ee692772.aspx#EBAA的脚本来访问注册表并使用 WMI 列出应用程序。

于 2012-01-24T18:52:43.680 回答
1

添加/删除程序还必须查看此注册表项以查找当前用户的安装:

HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Uninstall

Google Chrome、Dropbox 等应用程序或通过 JavaWS(网络启动)JNLP 安装的快捷方式只能在此处找到。

于 2011-04-07T07:55:23.080 回答
1

为了在控制面板的“程序和功能”中构建一个或多或少可靠的应用程序列表,您必须考虑并非所有应用程序都是使用 MSI 安装的。WMI 仅提供与 MSI 一起安装的那些。

以下是我发现的内容的简短摘要:

MSI 应用程序HKLM\...\Uninstall始终在和/或 下具有产品代码 (GUID) 子项HKLM\...\Installer\UserData\S-1-5-18\Products。此外,他们可能有一个看起来像HKLM\...\Uninstall\NotAGuid.

非 MSI 应用程序没有产品代码,因此具有类似HKLM\...\Uninstall\NotAGuid或的键HKCU\...\Uninstall\NotAGuid

于 2011-12-19T07:57:04.877 回答
1

希望这对某人有所帮助:我一直在我的脚本中使用基于注册表的枚举(如上面的一些答案所建议的那样),但发现当通过 SCCM 在 Windows 10 x64 上运行时它无法正确枚举 64 位软件(使用 32 位客户端)。在我的特殊情况下,发现这样的解决方案是最直接的解决方案:

Function Get-Programs($Bits) {
  $Result = @()
  $Output = (reg query HKLM\Software\Microsoft\Windows\CurrentVersion\Uninstall /reg:$Bits /s)

  Foreach ($Line in $Output) {
    If ($Line -match '^\s+DisplayName\s+REG_SZ\s+(.+?)$') {
      $Result += New-Object PSObject -Property @{
        DisplayName = $matches[1];
        Bits = "$($Bits)-bit";
      }
    }
  }

  $Result
}

$Software  = Get-Programs 32
$Software += Get-Programs 64

意识到这有点过于 Perl-ish,但我见过的所有其他替代方案都涉及包装脚本和类似的聪明聪明的解决方案的疯狂,这似乎更人性化。

PS 非常努力地避免在这里向微软倾倒大量盐,因为这使得一件绝对微不足道的事情几乎是不可能的。即,枚举网络上使用的所有 MS Office 版本是一项让成年人哭泣的任务。

于 2018-02-24T08:54:49.190 回答
1

自从提出这个问题以来,随着时间的推移,时间已经过去了很多......

现在有一个 WMI 类可用于注册表中的卸载条目。这比 Win32_Product 引用起来要快得多,我认为 Win32_Product 也会在列表上运行验证,并且可能需要一段时间才能枚举。下面的 Powershell 代码(可能需要 Powershell 3 或更高版本)将列出所有条目(Out-Gridview 部分只是为了漂亮的显示)。

Get-CimInstance Win32Reg_AddRemovePrograms | Out-gridview
于 2019-07-04T15:55:17.767 回答
0

我根据自己的需要调整了 MS-Technet VBScript。它将 Wow6432Node 以及标准条目转储到“programms.txt”中使用它需要您自担风险,不提供任何担保!

另存为转储.vbs

从命令行输入:wscript dump.vbs

Const HKLM = &H80000002
Set objReg = GetObject("winmgmts://" & "." & "/root/default:StdRegProv")
Set objFSO = CreateObject("Scripting.FileSystemObject")

outFile="programms.txt"

Set objFile = objFSO.CreateTextFile(outFile,True)
writeList "SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\", objReg, objFile
writeList "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\", objReg, objFile
objFile.Close 

Function writeList(strBaseKey, objReg, objFile) 
objReg.EnumKey HKLM, strBaseKey, arrSubKeys 
    For Each strSubKey In arrSubKeys
        intRet = objReg.GetStringValue(HKLM, strBaseKey & strSubKey, "DisplayName", strValue)
        If intRet <> 0 Then
            intRet = objReg.GetStringValue(HKLM, strBaseKey & strSubKey, "QuietDisplayName", strValue)
        End If
        objReg.GetStringValue HKLM, strBaseKey & strSubKey, "DisplayVersion", version
        objReg.GetStringValue HKLM, strBaseKey & strSubKey, "InstallDate", insDate 
        If (strValue <> "") and (intRet = 0) Then
            objFile.Write strValue & "," & version & "," & insDate & vbCrLf
        End If
    Next
End Function
于 2016-06-24T11:15:08.560 回答