Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/windows/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Windows 通过注册表检测已安装的程序_Windows_Registry - Fatal编程技术网

Windows 通过注册表检测已安装的程序

Windows 通过注册表检测已安装的程序,windows,registry,Windows,Registry,我需要开发一个过程,检测用户的计算机是否安装了某些程序,如果安装了,是什么版本。我相信我需要一个注册表位置和键的列表来查找并将其提供给程序,这不是一个问题。有没有更好的方法来实现这一点 我的第一个想法是在卸载条目中签入注册表,但我希望检测的应用程序中似乎有一个没有。所有使用注册表的应用程序进入注册表的标准位置是什么?似乎寻找特定于已安装程序的东西会更好,但HKCU\Software和HKLM\Software是需要寻找的地方。在64位系统上,x64键是: HKEY_LOCAL_MACHINE\S

我需要开发一个过程,检测用户的计算机是否安装了某些程序,如果安装了,是什么版本。我相信我需要一个注册表位置和键的列表来查找并将其提供给程序,这不是一个问题。有没有更好的方法来实现这一点


我的第一个想法是在卸载条目中签入注册表,但我希望检测的应用程序中似乎有一个没有。所有使用注册表的应用程序进入注册表的标准位置是什么?

似乎寻找特定于已安装程序的东西会更好,但HKCU\Software和HKLM\Software是需要寻找的地方。

在64位系统上,x64键是:

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall
大多数程序都列在那里。看看这些钥匙:
DisplayName
DisplayVersion

请注意,最后一个不是始终设置的

在64位系统上,x86密钥(通常包含更多条目)为:


您可以使用MSI API枚举Windows Installer安装的所有内容,但这不会列出计算机上可用的所有软件。在不知道你需要什么的情况下,我认为“已安装”的概念有点模糊。将软件部署到系统的方法有很多,从复杂的大型安装程序到ZIP文件,以及介于两者之间的所有内容。

用户特定的设置应写入HKCU\software,机器特定的设置应写入HKLM\software。在这些键下,结构
[软件供应商名称]\[应用程序名称]
(例如
HKLM\software\Microsoft\internetexplorer
)可能是最常见的,但这只是一种惯例,不是自然法则

许多(大多数?)应用程序还将其卸载条目添加到
HKLM\Software\Microsoft\Windows\CurrentVersion\uninstall\[app name]
,但并非所有应用程序都这样做

这些是最重要的关键;但是,注册表的内容不一定要准确地表示已安装的软件-可能应用程序只安装了一次,然后被手动删除,或者卸载程序没有删除它的所有痕迹。如果您想确定,请检查文件系统,查看应用程序是否仍然存在于其注册表项显示的位置

编辑:

如果您是组管理员的成员,您可以检查
HKEY_用户
hive-每个用户的HKCU实际驻留在那里(您需要知道用户SID,或者查看所有用户)


注:正如@Brian Ensink所说,“已安装”是一个模糊的概念——我们是否在试图找到用户可以运行的功能?有些软件甚至根本不会写入注册表:搜索“便携式应用程序”,查看经过专门修改的应用程序,以便直接从媒体(CD/USB)运行,并且不会在计算机上留下任何痕迹。我们可能还需要扫描磁盘、网络磁盘、用户下载的任何内容以及Internet上世界可访问的Windows共享(是的,这些东西是合法存在的-
\\live.sysinternals.com\tools
)。在这个方向上,用户可以运行的内容没有真正的限制,除非受到系统策略的阻止。

应用程序不需要任何注册表项。事实上,许多应用程序根本不需要安装。U3 U盘就是一个很好的例子;上面的程序只是从文件系统运行

如前所述,大多数好的应用程序都可以通过其卸载注册表项找到。这实际上是一对密钥,每个用户和每台机器(HKCU/HKLM-Piskvor只提到了HKLM)。不过,它并不(总是)提供安装目录

如果是在香港中文大学,那么你必须意识到
HKEY_CURRENT_USER
真正的意思是“CURRENT USER”。其他用户有自己的HKCU条目和自己安装的软件。你找不到。在具有漫游配置文件的公司网络上,阅读每个HKEY_用户的蜂巢是一场灾难。你真的不想从你遥远的[美国|中国|欧洲]办事处拿到1000个账户

即使安装了一个应用程序,并且您知道它的位置,它也可能与您的“版本”概念不同。最好的源是可执行文件中的“版本”资源。这确实是一个复数形式,所以您必须找到所有的版本,从所有版本中提取版本资源,并在发生冲突的情况下做出合理的决定


祝你好运。失败的方法有很多种。

Win32\u产品从不显示所有内容,只显示通过MSI安装程序安装的软件(据我所知)


有很多软件包是通过其他安装程序安装的,但没有显示在那里。需要另一种方法。

除了上面提到的所有注册表项外,您可能还需要查看HKEY_CURRENT_USER\Software\Microsoft\Installer\Products,以了解仅为当前用户安装的程序。

您可以使用PowerShell脚本查看注册表并获取已安装程序的详细信息。下面的脚本将生成一个包含已安装程序完整列表的文件。以“.ps”扩展名保存该文件,然后双击该文件

#
# Generates a full list of installed programs.
#

# Temporary auxiliar file.
$tmpFile = "tmp.txt"

# File that will hold the programs list.
$fileName = "programas-instalados.txt"

# Columns separator.
$separator = ","

# Delete previous files.
Remove-Item $tmpFile
Remove-Item $fileName

# Creates the temporary file.
Create-Item $tmpFile

# Searchs register for programs - part 1
$loc = Get-ChildItem HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall
$names = $loc |foreach-object {Get-ItemProperty $_.PsPath}
foreach ($name in $names)
{
    IF(-Not [string]::IsNullOrEmpty($name.DisplayName)) {      
        $line = $name.DisplayName+$separator+$name.DisplayVersion+$separator+$name.InstallDate
        Write-Host $line
        Add-Content $tmpFile "$line`n"        
    }
}

# Searchs register for programs - part 2
$loc = Get-ChildItem HKLM:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall
$names = $loc |foreach-object {Get-ItemProperty $_.PsPath}
foreach ($name in $names)
{
    IF(-Not [string]::IsNullOrEmpty($name.DisplayName)) {      
        $line = $name.DisplayName+$separator+$name.DisplayVersion+$separator+$name.InstallDate
        Write-Host $line
        Add-Content $tmpFile "$line`n"
    }
}

# Sorts the result, removes duplicate lines and
# generates the final file.
gc $tmpFile | sort | get-unique > $filename

HKEY\U CURRENT\U USER\Software\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Compatibility Assistant\Persisted

如何填充添加/删除程序列表?我列出的应用程序中有一半以上在上述位置没有注册表项(不包括Microsoft应用程序)。此外,非管理员用户可以安装不属于HKLM的软件。这是很常见的,它允许每个用户安装。一些用户安装的应用程序,如Chrome、GoToMeeting、Pixie、WinDirStat和WebEx不会写入HKLM \…\Uninstall。HKCU仅针对当前用户,因此除非用户是您,否则这些内容不会包含用户(非管理员)安装软件的条目。@Bratch:是的,您是正确的。增加了HKEY_用户-管理员可以通过这种方式访问其他用户的HKCU;另外,还有一段关于安装免费应用程序的内容。不知道\\live.sysinternals.com\tools。大提示
#
# Generates a full list of installed programs.
#

# Temporary auxiliar file.
$tmpFile = "tmp.txt"

# File that will hold the programs list.
$fileName = "programas-instalados.txt"

# Columns separator.
$separator = ","

# Delete previous files.
Remove-Item $tmpFile
Remove-Item $fileName

# Creates the temporary file.
Create-Item $tmpFile

# Searchs register for programs - part 1
$loc = Get-ChildItem HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall
$names = $loc |foreach-object {Get-ItemProperty $_.PsPath}
foreach ($name in $names)
{
    IF(-Not [string]::IsNullOrEmpty($name.DisplayName)) {      
        $line = $name.DisplayName+$separator+$name.DisplayVersion+$separator+$name.InstallDate
        Write-Host $line
        Add-Content $tmpFile "$line`n"        
    }
}

# Searchs register for programs - part 2
$loc = Get-ChildItem HKLM:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall
$names = $loc |foreach-object {Get-ItemProperty $_.PsPath}
foreach ($name in $names)
{
    IF(-Not [string]::IsNullOrEmpty($name.DisplayName)) {      
        $line = $name.DisplayName+$separator+$name.DisplayVersion+$separator+$name.InstallDate
        Write-Host $line
        Add-Content $tmpFile "$line`n"
    }
}

# Sorts the result, removes duplicate lines and
# generates the final file.
gc $tmpFile | sort | get-unique > $filename