C# 获取系统中已安装的应用程序
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/908850/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Get installed applications in a system
提问by Sauron
How to get the applications installed in the system using c# code?
如何使用c#代码获取系统中安装的应用程序?
采纳答案by Xiaofu
Iterating through the registry key "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall" seems to give a comprehensive list of installed applications.
遍历注册表项“SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall”似乎给出了已安装应用程序的完整列表。
Aside from the example below, you can find a similar version to what I've done here.
除了下面的例子,你可以找到一个与我在这里所做的类似的版本。
This is a rough example, you'll probaby want to do something to strip out blank rows like in the 2nd link provided.
这是一个粗略的例子,您可能想要做一些事情来去除提供的第二个链接中的空白行。
string registry_key = @"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall";
using(Microsoft.Win32.RegistryKey key = Registry.LocalMachine.OpenSubKey(registry_key))
{
foreach(string subkey_name in key.GetSubKeyNames())
{
using(RegistryKey subkey = key.OpenSubKey(subkey_name))
{
Console.WriteLine(subkey.GetValue("DisplayName"));
}
}
}
Alternatively, you can use WMI as has been mentioned:
或者,您可以使用 WMI,如前所述:
ManagementObjectSearcher mos = new ManagementObjectSearcher("SELECT * FROM Win32_Product");
foreach(ManagementObject mo in mos.Get())
{
Console.WriteLine(mo["Name"]);
}
But this is rather slower to execute, and I've heard it may only list programs installed under "ALLUSERS", though that may be incorrect. It also ignores the Windows components & updates, which may be handy for you.
但这执行起来相当慢,而且我听说它可能只列出安装在“ALLUSERS”下的程序,尽管这可能不正确。它还会忽略 Windows 组件和更新,这对您来说可能很方便。
回答by paxdiablo
Your best bet is to use WMI. Specifically the Win32_Productclass.
最好的办法是使用WMI。特别是Win32_Product类。
回答by Moayad Mardini
Iterate through "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall" keys and check their "DisplayName" values.
遍历“HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall”键并检查它们的“DisplayName”值。
回答by Kirtan
You can take a look at this article. It makes use of registry to read the list of installed applications.
你可以看看这篇文章。它利用注册表来读取已安装应用程序的列表。
public void GetInstalledApps()
{
string uninstallKey = @"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall";
using (RegistryKey rk = Registry.LocalMachine.OpenSubKey(uninstallKey))
{
foreach (string skName in rk.GetSubKeyNames())
{
using (RegistryKey sk = rk.OpenSubKey(skName))
{
try
{
lstInstalled.Items.Add(sk.GetValue("DisplayName"));
}
catch (Exception ex)
{ }
}
}
}
}
回答by Nick
Might I suggest you take a look at WMI (Windows Management Instrumentation). If you add the System.Management reference to your C# project, you'll gain access to the class `ManagementObjectSearcher', which you will probably find useful.
我是否建议您看看 WMI(Windows Management Instrumentation)。如果您将 System.Management 引用添加到您的 C# 项目,您将获得对“ManagementObjectSearcher”类的访问权限,您可能会发现它很有用。
There are various WMI Classes for Installed Applications, but if it was installed with Windows Installer, then the Win32_Product class is probably best suited to you.
已安装的应用程序有各种 WMI 类,但如果它是与 Windows Installer 一起安装的,那么 Win32_Product 类可能最适合您。
ManagementObjectSearcher s = new ManagementObjectSearcher("SELECT * FROM Win32_Product");
回答by Brian Haak
Use Windows Installer API!
使用 Windows 安装程序 API!
It allows to make reliable enumeration of all programs. Registry is not reliable, but WMI is heavyweight.
它允许对所有程序进行可靠的枚举。注册表不可靠,但 WMI 是重量级的。
回答by Marc Loeb
I used Nicks approach - I needed to check whether the Remote Tools for Visual Studio are installed or not, it seems a bit slow, but in a seperate thread this is fine for me. - here my extended code:
我使用了 Nicks 方法 - 我需要检查是否安装了 Visual Studio 的远程工具,这似乎有点慢,但在单独的线程中这对我来说很好。- 这是我的扩展代码:
private bool isRdInstalled() {
ManagementObjectSearcher p = new ManagementObjectSearcher("SELECT * FROM Win32_Product");
foreach (ManagementObject program in p.Get()) {
if (program != null && program.GetPropertyValue("Name") != null && program.GetPropertyValue("Name").ToString().Contains("Microsoft Visual Studio 2012 Remote Debugger")) {
return true;
}
if (program != null && program.GetPropertyValue("Name") != null) {
Trace.WriteLine(program.GetPropertyValue("Name"));
}
}
return false;
}
回答by Akshita
it's worth noting that the Win32_Product WMI class represents products as they are installed by Windows Installer. not every application use windows installer
值得注意的是, Win32_Product WMI 类代表由Windows Installer 安装的产品。并非每个应用程序都使用 Windows 安装程序
however "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall" represents applications for 32 bit. For 64 bit you also need to traverse "HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall" and since not every software has a 64 bit version the total applications installed are a union of keys on both locations that have "UninstallString" Value with them.
然而,“SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall”代表 32 位应用程序。对于 64 位,您还需要遍历“HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall”,并且由于并非每个软件都有 64 位版本,因此安装的总应用程序是两个位置上具有“UninstallString”的键的联合价值与他们。
but the best options remains the same .traverse registry keys is a better approach since every application have an entry in registry[including the ones in Windows Installer].however the registry method is insecure as if anyone removes the corresponding key then you will not know the Application entry.On the contrary Altering the HKEY_Classes_ROOT\Installers is more tricky as it is linked with licensing issues such as Microsoft office or other products. for more robust solution you can always combine registry alternative with the WMI.
但最好的选择保持不变 .traverse 注册表项是更好的方法,因为每个应用程序在注册表中都有一个条目 [包括 Windows Installer 中的条目]。但是注册表方法是不安全的,好像有人删除了相应的键,那么您将不知道应用程序条目。相反,更改 HKEY_Classes_ROOT\Installers 更加棘手,因为它与 Microsoft Office 或其他产品等许可问题有关。要获得更强大的解决方案,您始终可以将注册表替代方案与 WMI 结合使用。
回答by Stephen Walter
I agree that enumerating through the registry key is the best way.
我同意通过注册表项进行枚举是最好的方法。
Note, however, that the key given, @"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
, will list all applications in a 32-bit Windows installation, and 64-bit applications in a Windows 64-bit installation.
但是请注意,给定的密钥@"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
将列出 32 位 Windows 安装中的所有应用程序,以及 Windows 64 位安装中的 64 位应用程序。
In order to also see 32-bit applications installed on a Windows 64-bit installation, you would also need to enumeration the key @"SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
.
为了同时查看 Windows 64 位安装上安装的 32 位应用程序,您还需要枚举密钥@"SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
.
回答by Pardha Saradhi Vanjarpau
My requirement is to check if specific software is installed in my system. This solution works as expected. It might help you. I used a windows application in c# with visual studio 2015.
我的要求是检查我的系统中是否安装了特定软件。此解决方案按预期工作。它可能会帮助你。我在 Visual Studio 2015 中使用了 c# 中的 Windows 应用程序。
private void Form1_Load(object sender, EventArgs e)
{
object line;
string softwareinstallpath = string.Empty;
string registry_key = @"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall";
using (var baseKey = Microsoft.Win32.RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry64))
{
using (var key = baseKey.OpenSubKey(registry_key))
{
foreach (string subkey_name in key.GetSubKeyNames())
{
using (var subKey = key.OpenSubKey(subkey_name))
{
line = subKey.GetValue("DisplayName");
if (line != null && (line.ToString().ToUpper().Contains("SPARK")))
{
softwareinstallpath = subKey.GetValue("InstallLocation").ToString();
listBox1.Items.Add(subKey.GetValue("InstallLocation"));
break;
}
}
}
}
}
if(softwareinstallpath.Equals(string.Empty))
{
MessageBox.Show("The Mirth connect software not installed in this system.")
}
string targetPath = softwareinstallpath + @"\custom-lib\";
string[] files = System.IO.Directory.GetFiles(@"D:\BaseFiles");
// Copy the files and overwrite destination files if they already exist.
foreach (var item in files)
{
string srcfilepath = item;
string fileName = System.IO.Path.GetFileName(item);
System.IO.File.Copy(srcfilepath, targetPath + fileName, true);
}
return;
}