Xia*_*ofu 101
通过注册表项"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"进行迭代似乎提供了已安装应用程序的完整列表.
除了下面的示例,您可以找到与我在此处所做的相似的版本.
这是一个粗略的例子,你可能会想要做一些事情来删除像提供的第二个链接中的空白行.
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"));
}
}
}
Run Code Online (Sandbox Code Playgroud)
或者,您可以使用WMI,如上所述:
ManagementObjectSearcher mos = new ManagementObjectSearcher("SELECT * FROM Win32_Product");
foreach(ManagementObject mo in mos.Get())
{
Console.WriteLine(mo["Name"]);
}
Run Code Online (Sandbox Code Playgroud)
但执行速度相当慢,我听说它可能只列出"ALLUSERS"下安装的程序,尽管这可能不正确.它还忽略了Windows组件和更新,这对您来说可能很方便.
use*_*903 12
我希望能够提取出现在开始菜单中的应用程序列表。使用注册表,我得到的条目没有出现在开始菜单中。
我还想找到 exe 路径并提取一个图标以最终制作一个漂亮的启动器。不幸的是,使用注册表方法,这是一种命中和失误,因为我的观察是这些信息不可靠。
我的替代方案基于 shell:AppsFolder,您可以通过运行访问该文件夹,explorer.exe shell:appsFolder
其中列出了当前安装的所有应用程序,包括商店应用程序,这些应用程序可通过开始菜单获得。问题是这是一个无法使用System.IO.Directory
. 相反,您必须使用本机 shell32 命令。幸运的是,微软在 Nuget 上发布了Microsoft.WindowsAPICodePack-Shell,它是上述命令的包装器。话不多说,代码如下:
// 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;
}
Run Code Online (Sandbox Code Playgroud)
这就是全部。您还可以使用启动应用程序
System.Diagnostics.Process.Start("explorer.exe", @" shell:appsFolder\" + appModelUserID);
Run Code Online (Sandbox Code Playgroud)
这适用于常规 Win32 应用程序和 UWP 商店应用程序。他们苹果怎么样。
由于您有兴趣列出所有已安装的应用程序,因此有理由期望您可能还想监视新应用程序或已卸载的应用程序,您可以使用ShellObjectWatcher
:
ShellObjectWatcher sow = new ShellObjectWatcher(appsFolder, false);
sow.AllEvents += (s, e) => DoWhatever();
sow.Start();
Run Code Online (Sandbox Code Playgroud)
编辑:人们可能还想知道上面提到的 AppUserMoedlID 是Windows 用于对 taskbar 中的窗口进行分组的唯一 ID。
Kir*_*tan 10
你可以看一下这篇文章.它使用注册表来读取已安装的应用程序列表.
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)
{ }
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
小智 8
我同意通过注册表项枚举是最好的方法.
但请注意,给定的密钥@"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
将列出32位Windows安装中的所有应用程序,以及Windows 64位安装中的64位应用程序.
为了还能看到在Windows 64位安装上安装的32位应用程序,您还需要枚举密钥@"SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
.
值得注意的是,Win32_Product WMI类代表Windows Installer安装的产品[ http://msdn.microsoft.com/en-us/library/aa394378%28v=vs.85%29.aspx].不是每个应用程序使用Windows安装程序
但是"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"表示32位应用程序.对于64位,您还需要遍历"HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall",并且由于并非每个软件都具有64位版本,因此安装的总应用程序是两个位置上具有"UninstallString"的键的并集.值得他们.
但最好的选项仍然是相同的.traverse注册表项是一种更好的方法,因为每个应用程序在注册表中都有一个条目[包括Windows Installer中的条目].但是注册表方法是不安全的,好像有人删除了相应的密钥然后你就不会知道了应用程序条目.相反,更改HKEY_Classes_ROOT \安装程序更加棘手,因为它与Microsoft办公室或其他产品等许可问题相关联.对于更强大的解决方案,您始终可以将注册表替代与WMI结合使用.
虽然接受的解决方案有效,但它并不完整。到目前为止。
如果你想获得所有的钥匙,你还需要考虑两件事:
x86 和 x64 应用程序无法访问相同的注册表。基本上 x86 无法正常访问 x64 注册表。并且某些应用程序仅注册到 x64 注册表。
和
一些应用程序实际上安装到 CurrentUser 注册表而不是 LocalMachine
考虑到这一点,我设法使用以下代码获得了所有已安装的应用程序,而无需使用 WMI
这是代码:
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)
{ }
}
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
114371 次 |
最近记录: |