C# 在系统中获取已安装的应用程序
如何使用c代码在系统中安装应用程序?您最好的选择是使用。特别是类。遍历“HKEY\U LOCAL\U MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall”键并检查其“DisplayName”值。您可以查看。它利用注册表读取已安装应用程序的列表C# 在系统中获取已安装的应用程序,c#,.net,installation,C#,.net,Installation,如何使用c代码在系统中安装应用程序?您最好的选择是使用。特别是类。遍历“HKEY\U LOCAL\U MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall”键并检查其“DisplayName”值。您可以查看。它利用注册表读取已安装应用程序的列表 public void GetInstalledApps() { string uninstallKey = @"SOFTWARE\Microsoft\Windows\Curren
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)
{ }
}
}
}
}
我建议您看看WMI()。 如果将System.Management引用添加到C#项目中,您将获得对“ManagementObjectSearcher”类的访问权限,您可能会发现该类很有用 有各种各样的WMI类,但是如果它是与Windows Installer一起安装的,那么Win32_产品类可能最适合您
ManagementObjectSearcher s = new ManagementObjectSearcher("SELECT * FROM Win32_Product");
遍历注册表项“SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall”似乎可以提供已安装应用程序的全面列表
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)
{ }
}
}
}
}
除了下面的例子之外,你可以找到一个与我所做的类似的版本
这是一个粗略的示例,您可能想做一些事情来去掉空行,如提供的第二个链接中所示
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"));
}
}
}
或者,您可以使用WMI,如上所述:
ManagementObjectSearcher mos = new ManagementObjectSearcher("SELECT * FROM Win32_Product");
foreach(ManagementObject mo in mos.Get())
{
Console.WriteLine(mo["Name"]);
}
但这执行起来相当慢,我听说它可能只列出在“ALLUSERS”下安装的程序,尽管这可能是不正确的。它还会忽略Windows组件和更新,这对您可能很方便。使用Windows Installer API
它允许对所有程序进行可靠的枚举。注册表不可靠,但WMI是重量级的。我使用了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;
}
值得注意的是,Win32_Product WMI类表示由安装的产品。并非所有应用程序都使用windows installer 但是,“SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall”表示32位的应用程序。对于64位,您还需要遍历“HKEY\U LOCAL\U MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall”,并且由于并非每个软件都有64位版本,因此安装的所有应用程序都是两个位置上具有“UninstallString”值的键的并集 但最好的选择仍然是一样的。遍历注册表项是一种更好的方法,因为每个应用程序在注册表中都有一个条目[包括Windows Installer中的条目]。但是,注册表方法是不安全的,因为如果有人删除了相应的项,则您将不知道应用程序项。相反,更改HKEY_Classes_ROOT\Installer更为棘手,因为它与许可问题(如Microsoft office或其他产品)有关。
要获得更健壮的解决方案,您可以始终将注册表替代方案与WMI结合起来。我同意通过注册表项枚举是最好的方法 注意,但是,给定的键“SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall”将列出32位Windows安装中的所有应用程序,以及64位Windows安装中的64位应用程序
为了查看Windows 64位安装上安装的32位应用程序,您还需要枚举键“SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall”我的要求是检查我的系统中是否安装了特定的软件。此解决方案按预期工作。这可能对你有帮助。我在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;
}
我希望能够提取应用程序列表,就像它们出现在“开始”菜单中一样。使用注册表,我得到的条目不会显示在“开始”菜单中 我还想找到exe路径并提取一个图标,最终制作一个漂亮的启动器。不幸的是,对于registry方法,这是一种偶然的结果,因为根据我的观察,这些信息不可靠 我的备选方案是基于shell:AppsFolder,您可以通过运行
explorer.exe来访问该shell:AppsFolder
,它列出了当前安装并通过“开始”菜单可用的所有应用程序,包括商店应用程序。问题是这是一个虚拟文件夹,无法使用System.IO.Directory
访问。相反,您必须使用本机shell32命令。幸运的是,微软发布了Nuget,它是上述命令的包装器。说得够多了,下面是代码:
// GUID taken from https://docs.microsoft.com/en-us/windows/win32/shell/knownfolderid
var FOLDERID_AppsFolder = new Guid("{1e87508d-89c2-42f0-8a7e-645a0f50ca58}");
ShellObject appsFolder = (ShellObject)KnownFolderHelper.FromKnownFolderId(FOLDERID_AppsFolder);
foreach (var app in (IKnownFolder)appsFolder)
{
// The friendly app name
string name = app.Name;
// The ParsingName property is the AppUserModelID
string appUserModelID = app.ParsingName; // or app.Properties.System.AppUserModel.ID
// You can even get the Jumbo icon in one shot
ImageSource icon = app.Thumbnail.ExtraLargeBitmapSource;
}
List<string> installs = new List<string>();
List<string> keys = new List<string>() {
@"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall",
@"SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
};
// The RegistryView.Registry64 forces the application to open the registry as x64 even if the application is compiled as x86
FindInstalls(RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry64), keys, installs);
FindInstalls(RegistryKey.OpenBaseKey(RegistryHive.CurrentUser, RegistryView.Registry64), keys, installs);
installs = installs.Where(s => !string.IsNullOrWhiteSpace(s)).Distinct().ToList();
installs.Sort(); // The list of ALL installed applications
private void FindInstalls(RegistryKey regKey, List<string> keys, List<string> installed)
{
foreach (string key in keys)
{
using (RegistryKey rk = regKey.OpenSubKey(key))
{
if (rk == null)
{
continue;
}
foreach (string skName in rk.GetSubKeyNames())
{
using (RegistryKey sk = rk.OpenSubKey(skName))
{
try
{
installed.Add(Convert.ToString(sk.GetValue("DisplayName")));
}
catch (Exception ex)
{ }
}
}
}
}
}
这就是全部。您还可以使用启动应用程序
System.Diagnostics.Process.Start("explorer.exe", @" shell:appsFolder\" + appModelUserID);
这适用于常规Win32应用程序和UWP应用商店应用程序。苹果怎么样
由于您对列出所有已安装的应用程序感兴趣,因此有理由认为您可能希望监视新的应用程序或已卸载的应用程序,您可以使用ShellObjectWatcher
:
ShellObjectWatcher sow = new ShellObjectWatcher(appsFolder, false);
sow.AllEvents += (s, e) => DoWhatever();
sow.Start();
编辑:您可能还想知道上面提到的AppUserMoedId是。虽然接受的解决方案有效,但它并不完整。到目前为止 如果您想获得所有钥匙,还需要考虑两件事: x86和x64应用程序无权访问同一注册表。 基本上x86无法正常访问x64注册表。还有一些 应用程序仅注册到x64注册表 及 有些应用程序实际上安装到CurrentUser注册表中,而不是本地计算机 考虑到这一点,我设法使用以下代码获取所有已安装的应用程序,而不使用WMI 代码如下:
// GUID taken from https://docs.microsoft.com/en-us/windows/win32/shell/knownfolderid
var FOLDERID_AppsFolder = new Guid("{1e87508d-89c2-42f0-8a7e-645a0f50ca58}");
ShellObject appsFolder = (ShellObject)KnownFolderHelper.FromKnownFolderId(FOLDERID_AppsFolder);
foreach (var app in (IKnownFolder)appsFolder)
{
// The friendly app name
string name = app.Name;
// The ParsingName property is the AppUserModelID
string appUserModelID = app.ParsingName; // or app.Properties.System.AppUserModel.ID
// You can even get the Jumbo icon in one shot
ImageSource icon = app.Thumbnail.ExtraLargeBitmapSource;
}
List<string> installs = new List<string>();
List<string> keys = new List<string>() {
@"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall",
@"SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
};
// The RegistryView.Registry64 forces the application to open the registry as x64 even if the application is compiled as x86
FindInstalls(RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry64), keys, installs);
FindInstalls(RegistryKey.OpenBaseKey(RegistryHive.CurrentUser, RegistryView.Registry64), keys, installs);
installs = installs.Where(s => !string.IsNullOrWhiteSpace(s)).Distinct().ToList();
installs.Sort(); // The list of ALL installed applications
private void FindInstalls(RegistryKey regKey, List<string> keys, List<string> installed)
{
foreach (string key in keys)
{
using (RegistryKey rk = regKey.OpenSubKey(key))
{
if (rk == null)
{
continue;
}
foreach (string skName in rk.GetSubKeyNames())
{
using (RegistryKey sk = rk.OpenSubKey(skName))
{
try
{
installed.Add(Convert.ToString(sk.GetValue("DisplayName")));
}
catch (Exception ex)
{ }
}
}
}
}
}
List installs=newlist();
列表键=新列表(){
@“软件\Microsoft\Windows\CurrentVersion\Uninstall”,
@“软件\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall”
};
//RegistryView.Registry64强制应用程序以x64的形式打开注册表,即使应用程序编译为x86
FindInstalls(RegistryKey.OpenBaseKey