Get installed applications in a system

后端 未结 14 995
遥遥无期
遥遥无期 2020-11-22 08:28

How to get the applications installed in the system using c# code?

相关标签:
14条回答
  • 2020-11-22 09:16

    Your best bet is to use WMI. Specifically the Win32_Product class.

    0 讨论(0)
  • 2020-11-22 09:19

    As others have pointed out, the accepted answer does not return both x86 and x64 installs. Below is my solution for that. It creates a StringBuilder, appends the registry values to it (with formatting), and writes its output to a text file:

    const string FORMAT = "{0,-100} {1,-20} {2,-30} {3,-8}\n";
    
    private void LogInstalledSoftware()
    {
        var line = string.Format(FORMAT, "DisplayName", "Version", "Publisher", "InstallDate");
        line += string.Format(FORMAT, "-----------", "-------", "---------", "-----------");
        var sb = new StringBuilder(line, 100000);
        ReadRegistryUninstall(ref sb, RegistryView.Registry32);
        sb.Append($"\n[64 bit section]\n\n{line}");
        ReadRegistryUninstall(ref sb, RegistryView.Registry64);
        File.WriteAllText(@"c:\temp\log.txt", sb.ToString());
    }
    
       private static void ReadRegistryUninstall(ref StringBuilder sb, RegistryView view)
        {
            const string REGISTRY_KEY = @"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall";
            using var baseKey = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, view);
            using var subKey = baseKey.OpenSubKey(REGISTRY_KEY);
            foreach (string subkey_name in subKey.GetSubKeyNames())
            {
                using RegistryKey key = subKey.OpenSubKey(subkey_name);
                if (!string.IsNullOrEmpty(key.GetValue("DisplayName") as string))
                {
                    var line = string.Format(FORMAT,
                        key.GetValue("DisplayName"),
                        key.GetValue("DisplayVersion"),
                        key.GetValue("Publisher"),
                        key.GetValue("InstallDate"));
                    sb.Append(line);
                }
                key.Close();
            }
            subKey.Close();
            baseKey.Close();
        }
    
    0 讨论(0)
  • 2020-11-22 09:20

    I wanted to be able to extract a list of apps just as they appear in the start menu. Using the registry, I was getting entries that do not show up in the start menu.

    I also wanted to find the exe path and to extract an icon to eventually make a nice looking launcher. Unfortunately, with the registry method this is kind of a hit and miss since my observations are that this information isn't reliably available.

    My alternative is based around the shell:AppsFolder which you can access by running explorer.exe shell:appsFolder and which lists all apps, including store apps, currently installed and available through the start menu. The issue is that this is a virtual folder that can't be accessed with System.IO.Directory. Instead, you would have to use native shell32 commands. Fortunately, Microsoft published the Microsoft.WindowsAPICodePack-Shell on Nuget which is a wrapper for the aforementioned commands. Enough said, here's the code:

    // 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;
    }
    

    And that's all there is to it. You can also start the apps using

    System.Diagnostics.Process.Start("explorer.exe", @" shell:appsFolder\" + appModelUserID);
    

    This works for regular Win32 apps and UWP store apps. How about them apples.

    Since you are interested in listing all installed apps, it is reasonable to expect that you might want to monitor for new apps or uninstalled apps as well, which you can do using the ShellObjectWatcher:

    ShellObjectWatcher sow = new ShellObjectWatcher(appsFolder, false);
    sow.AllEvents += (s, e) => DoWhatever();
    sow.Start();
    

    Edit: One might also be interested in knowing that the AppUserMoedlID mentioned above is the unique ID Windows uses to group windows in the taskbar.

    0 讨论(0)
  • 2020-11-22 09:20

    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.

    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.

    ManagementObjectSearcher s = new ManagementObjectSearcher("SELECT * FROM Win32_Product");
    
    0 讨论(0)
  • 2020-11-22 09:22

    The object for the list:

    public class InstalledProgram
    {
        public string DisplayName { get; set; }
        public string Version { get; set; }
        public string InstalledDate { get; set; }
        public string Publisher { get; set; }
        public string UnninstallCommand { get; set; }
        public string ModifyPath { get; set; }
    }
    

    The call for creating the list:

        List<InstalledProgram> installedprograms = new List<InstalledProgram>();
        string registry_key = @"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall";
        using (RegistryKey key = Registry.LocalMachine.OpenSubKey(registry_key))
        {
            foreach (string subkey_name in key.GetSubKeyNames())
            {
                using (RegistryKey subkey = key.OpenSubKey(subkey_name))
                {
                    if (subkey.GetValue("DisplayName") != null)
                    {
                        installedprograms.Add(new InstalledProgram
                        {
                            DisplayName = (string)subkey.GetValue("DisplayName"),
                            Version = (string)subkey.GetValue("DisplayVersion"),
                            InstalledDate = (string)subkey.GetValue("InstallDate"),
                            Publisher = (string)subkey.GetValue("Publisher"),
                            UnninstallCommand = (string)subkey.GetValue("UninstallString"),
                            ModifyPath = (string)subkey.GetValue("ModifyPath")
                        });
                    }
                }
            }
        }
    
    0 讨论(0)
  • 2020-11-22 09:24

    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.

    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".

    0 讨论(0)
提交回复
热议问题