Comment obtenir les applications installées dans le système en utilisant le code c #?
Une itération dans la clé de registre "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall" semble donner une liste complète des applications installées.
En plus de l'exemple ci-dessous, vous pouvez trouver une version similaire à ce que j'ai fait ici .
Ceci est un exemple approximatif, vous voudrez probablement faire quelque chose pour effacer les lignes vides, comme dans le deuxième lien fourni.
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"));
}
}
}
Alternativement, vous pouvez utiliser WMI comme cela a été mentionné:
ManagementObjectSearcher mos = new ManagementObjectSearcher("SELECT * FROM Win32_Product");
foreach(ManagementObject mo in mos.Get())
{
Console.WriteLine(mo["Name"]);
}
Mais l’exécution est plutôt lente, et j’ai entendu dire que la liste des programmes installés sous "ALLUSERS" est peut-être répertoriée, bien que cela puisse être incorrect. Il ignore également les composants Windows et les mises à jour, ce qui peut vous être utile.
Vous pouvez jeter un oeil à cet article . Il utilise le registre pour lire la liste des applications installées.
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)
{ }
}
}
}
}
Je conviens que l'énumération à travers la clé de registre est la meilleure solution.
Note, cependant, que la clé donnée, @"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
, listera toutes les applications d’une installation Windows 32 bits et les applications 64 bits d’une installation Windows 64 bits.
Pour voir également les applications 32 bits installées sur une installation Windows 64 bits, vous devez également énumérer la clé @"SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
.
il est à noter que la classe Win32_Product WMI représente les produits tels qu'ils sont installés par Windows Installer . toutes les applications n'utilisent pas l'installateur Windows
toutefois, "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall" représente les applications 32 bits. Pour le 64 bits, vous devez également parcourir "HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall" et comme tous les logiciels ne possèdent pas une version 64 bits, le nombre total d'applications installées est une union de clés sur les deux emplacements dotés de "UninstallString". Valeur avec eux.
mais les meilleures options restent les mêmes. Les clés de registre .traverse sont une meilleure approche puisque chaque application a une entrée dans le registre [y compris celles de Windows Installer]. Cependant, la méthode de registre n'est pas sécurisée, comme si quelqu'un retirait la clé correspondante, vous ne le saurez pas. l'entrée de l'application. Au contraire, modifier HKEY_Classes_ROOT\Installers est plus délicat, car il est lié à des problèmes de licence tels que Microsoft Office ou d'autres produits. pour une solution plus robuste, vous pouvez toujours combiner une alternative de registre avec le WMI.
Parcourez les clés "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall" et vérifiez leurs valeurs "DisplayName".
Utilisez l'API Windows Installer!
Cela permet de faire une énumération fiable de tous les programmes. Le registre n'est pas fiable, mais WMI est un poids lourd.
Votre meilleur pari est d'utiliser WMI . Spécifiquement, la classe Win32_Product .
Puis-je vous suggérer d’examiner WMI ( Windows Management Instrumentation ). Si vous ajoutez la référence System.Management à votre projet C #, vous aurez accès à la classe `ManagementObjectSearcher ', que vous jugerez probablement utile.
Il existe différentes classes WMI pour applications installées , mais si elle a été installée avec Windows Installer, la classe Win32_Product vous conviendra probablement le mieux.
ManagementObjectSearcher s = new ManagementObjectSearcher("SELECT * FROM Win32_Product");
Je voulais pouvoir extraire une liste d'applications telles qu'elles apparaissent dans le menu Démarrer. En utilisant le registre, je obtenais des entrées qui n'apparaissent pas dans le menu Démarrer.
Je voulais aussi trouver le chemin exe et extraire une icône pour éventuellement créer un lanceur à la recherche de Nice. Malheureusement, avec la méthode du registre, c'est un peu un hasard, car mes observations sont que cette information n'est pas fiable.
Mon alternative est basée sur le shell: AppsFolder auquel vous pouvez accéder en exécutant Explorer.exe Shell:appsFolder
et qui répertorie toutes les applications, y compris les applications stockées, actuellement installées et disponibles via le menu Démarrer. Le problème est qu’il s’agit d’un dossier virtuel inaccessible avec System.IO.Directory
. Au lieu de cela, vous devrez utiliser des commandes natives Shell32. Heureusement, Microsoft a publié le Microsoft.WindowsICodePack-Shell sur Nuget, qui encapsule les commandes susmentionnées. Assez dit, voici le code:
// GUID taken from https://docs.Microsoft.com/en-us/windows/win32/Shell/knownfolderid
var FODLERID_AppsFolder = new Guid("{1e87508d-89c2-42f0-8a7e-645a0f50ca58}");
ShellObject appsFolder = (ShellObject)KnownFolderHelper.FromKnownFolderId(FODLERID_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;
}
Et c'est tout ce qu'il y a à faire. Vous pouvez également démarrer les applications en utilisant
System.Diagnostics.Process.Start("Explorer.exe", @" Shell:appsFolder\" + appModelUserID);
Cela fonctionne pour les applications Win32 normales et les applications de magasin UWP. Qu'en est-il des pommes.
Puisque vous souhaitez répertorier toutes les applications installées, il est raisonnable de penser que vous voudrez peut-être également surveiller les nouvelles applications ou les applications désinstallées, ce que vous pouvez faire à l'aide de la commande ShellObjectWatcher
:
ShellObjectWatcher sow = new ShellObjectWatcher(appsFolder, false);
sow.AllEvents += (s, e) => DoWhatever();
sow.Start();
Edit: Vous pouvez également être intéressé par le fait que l’AppUserMoedlID mentionné ci-dessus est le ID unique utilisé par Windows pour regrouper les fenêtres dans la barre des tâches .
Mon exigence est de vérifier si un logiciel spécifique est installé sur mon système. Cette solution fonctionne comme prévu. Cela pourrait vous aider. J'ai utilisé une application Windows en C # avec Visual Studio 2015.
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;
}
J'ai utilisé l'approche Nicks - je devais vérifier si les outils à distance pour Visual Studio sont installés ou non, cela semble un peu lent, mais dans un fil séparé, cela me convient parfaitement. - voici mon code étendu:
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;
}