Überprüfen Sie, ob die Anwendung in der Registrierung installiert ist

Lesezeit: 11 Minuten

Benutzer-Avatar
Hyperion

Im Moment verwende ich dies, um alle Anwendungen aufzulisten, die in der Registrierung für 32-Bit und 64 aufgeführt sind. Ich habe die anderen Beispiele gesehen, wie man ohne Erfolg überprüft, ob eine Anwendung installiert ist.

string registryKey = @"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall";
RegistryKey key = Registry.LocalMachine.OpenSubKey(registryKey);
if (key != null)
{
    foreach (String a in key.GetSubKeyNames())
    {
        RegistryKey subkey = key.OpenSubKey(a);
        Console.WriteLine(subkey.GetValue("DisplayName"));
    }
}

registryKey = @"SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall";
key = Registry.LocalMachine.OpenSubKey(registryKey);
if (key != null)
{
    foreach (String a in key.GetSubKeyNames())
    {
        RegistryKey subkey = key.OpenSubKey(a);
        Console.WriteLine(subkey.GetValue("DisplayName"));
    }
}

Dieser Ausschnitt listet also alles im Konsolenfenster auf, und was ich versuche, ist, nur einen Programmtitel aus der Liste der Anzeigenamen zu finden, um zu sehen, ob er installiert ist.

Das letzte, was ich versuchte, war

if (subkey.Name.Contains("OpenSSL"))
    Console.Writeline("OpenSSL Found");
else
    Console.Writeline("OpenSSL Not Found");

Alles, was ich versuchte, kam entweder falsch oder falsch positiv zurück. Kann mir jemand zeigen, wie ich einfach einen Titel aus der Liste holen kann?

Bitte veröffentlichen Sie nicht die bekannte private statische void IsApplicationInstalled(p_name)-Funktion. Es funktioniert bei mir überhaupt nicht.

  • Als Nebenbemerkung: Sie müssen Close() die Regkeys, die Sie haben Opened()‘d .. obwohl dies verwalteter Code ist, handelt es sich um nicht verwaltete Ressourcen, die auslaufen, wenn Sie sie nicht schließen.

    – Canhazbits

    4. Mai 2013 um 21:32 Uhr

  • Vielen Dank für die FYI dazu.

    – Hyperions

    4. Mai 2013 um 21:34 Uhr

  • Das klingt, als könnte es ganz nützlich sein. Je nachdem, wofür Sie es verwenden möchten, ist es jedoch möglicherweise besser, den installierten Code an die jeweilige Anwendung anzupassen, damit er schneller ausgeführt wird.

    – Sildoreth

    16. Juni 2014 um 21:15 Uhr


  • Außerdem werden nicht alle Programme in der “Deinstallationsliste” registriert. Nur zur Info.

    – Sildoreth

    16. Juni 2014 um 21:17 Uhr

Benutzer-Avatar
Hyperion

Nach der Suche und Fehlerbehebung habe ich es so zum Laufen gebracht:

public static bool checkInstalled (string c_name)
{
    string displayName;

    string registryKey = @"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall";
    RegistryKey key = Registry.LocalMachine.OpenSubKey(registryKey);
    if (key != null)
    {
        foreach (RegistryKey subkey in key.GetSubKeyNames().Select(keyName => key.OpenSubKey(keyName)))
        {
            displayName = subkey.GetValue("DisplayName") as string;
            if (displayName != null && displayName.Contains(c_name))
            {
                return true;
            }
        }
        key.Close();
    }

    registryKey = @"SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall";
    key = Registry.LocalMachine.OpenSubKey(registryKey);
    if (key != null)
    {
        foreach (RegistryKey subkey in key.GetSubKeyNames().Select(keyName => key.OpenSubKey(keyName)))
        {
            displayName = subkey.GetValue("DisplayName") as string;
            if (displayName != null && displayName.Contains(c_name))
            {
                return true;
            }
        }
        key.Close();
    }
    return false;
}

Und ich nenne es einfach nur mit

if(checkInstalled("Application Name"))

  • Diese Lösung wird nicht immer funktionieren, da nicht alle Einträge immer menschenlesbare Namen sind, die meisten Einträge sind GUIDs, dann müssen Sie überprüfen, welche Anwendung diese GUID darstellt

    – feldeOne

    19. September 2018 um 12:45 Uhr

  • @feldeOne Zu dieser Zeit diente dieser Code nur dazu, zu überprüfen, ob bestimmte Anwendungen mit angegebenen Ordnernamen installiert wurden

    – Hyperions

    20. September 2018 um 14:17 Uhr

  • @feldeOne es funktioniert nicht, wenn ich die Anwendung deinstalliere. Es zeigt immer noch, dass es auf meiner CPU liegt.

    – Mattenratte

    17. April 2020 um 8:41 Uhr

  • Das Problem ist, wenn Sie eine 32-Bit-Anwendung ausführen, werden 32-Bit-Programme zurückgegeben, wenn es 64-Bit sein sollte.

    – Silny ToJa

    7. Mai 2020 um 12:11 Uhr


Dies ist eine saubere Möglichkeit, dies ohne so viel Code zu tun.

    private static bool IsSoftwareInstalled(string softwareName)
    {
        var key = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall") ??
                  Registry.LocalMachine.OpenSubKey(
                      @"SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall");

        if (key == null)
            return false;

        return key.GetSubKeyNames()
            .Select(keyName => key.OpenSubKey(keyName))
            .Select(subkey => subkey.GetValue("DisplayName") as string)
            .Any(displayName => displayName != null && displayName.Contains(softwareName));
    }

Rufen Sie es mit einer if-Anweisung auf:

if (IsSoftwareInstalled("OpenSSL"))

  • dotnet fügen Sie das Paket Microsoft.Win32.Registry für diejenigen hinzu, die dies in dotnet standard/core benötigen

    – jb007

    13. Juni 2019 um 17:35 Uhr

  • Dieser Code muss als X64 ausgeführt werden oder in der Build-Einstellung des Projekts die Option „32-Bit bevorzugen“ deaktivieren.

    – Shanghai

    31. Oktober 2019 um 23:05 Uhr

Benutzer-Avatar
Mrocny Arturek

Ich habe den Code von @Stellan Lindell überprüft und er funktioniert nicht in allen Fällen. Meine Version sollte in allen Szenarien funktionieren und überprüft die spezifische Version der installierten Programme (x86, x64).

using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Win32;

namespace Test
{  
internal class Program
{  
    public enum ProgramVersion
    {
        x86,
        x64
    }

    private static IEnumerable<string> GetRegisterSubkeys(RegistryKey registryKey)
    {
        return registryKey.GetSubKeyNames()
                .Select(registryKey.OpenSubKey)
                .Select(subkey => subkey.GetValue("DisplayName") as string);
    }

    private static bool CheckNode(RegistryKey registryKey, string applicationName, ProgramVersion? programVersion)
    {
        return GetRegisterSubkeys(registryKey).Any(displayName => displayName != null
                                                                  && displayName.Contains(applicationName)
                                                                  && displayName.Contains(programVersion.ToString()));
    }

    private static bool CheckApplication(string registryKey, string applicationName, ProgramVersion? programVersion)
    {
        RegistryKey key = Registry.LocalMachine.OpenSubKey(registryKey);

        if (key != null)
        {
            if (CheckNode(key, applicationName, programVersion))
                return true;

            key.Close();
        }

        return false;
    }

    public static bool IsSoftwareInstalled(string applicationName, ProgramVersion? programVersion)
    {
        string[] registryKey = new [] {
            @"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall",
            @"SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
        };

        return registryKey.Any(key => CheckApplication(key, applicationName, programVersion));
    }

    private static void Main()
    {
        // Examples
        Console.WriteLine("Notepad++: " + IsSoftwareInstalled("Notepad++", null));
        Console.WriteLine("Notepad++(x86): " + IsSoftwareInstalled("Notepad++", ProgramVersion.x86));
        Console.WriteLine("Notepad++(x64): " + IsSoftwareInstalled("Notepad++", ProgramVersion.x64));
        Console.WriteLine("Microsoft Visual C++ 2009: " + IsSoftwareInstalled("Microsoft Visual C++ 2009", null));
        Console.WriteLine("Microsoft Visual C-- 2009: " + IsSoftwareInstalled("Microsoft Visual C-- 2009", null));
        Console.WriteLine("Microsoft Visual C++ 2013: " + IsSoftwareInstalled("Microsoft Visual C++ 2013", null));
        Console.WriteLine("Microsoft Visual C++ 2012 Redistributable (x86): " + IsSoftwareInstalled("Microsoft Visual C++ 2013", ProgramVersion.x86));
        Console.WriteLine("Microsoft Visual C++ 2012 Redistributable (x64): " + IsSoftwareInstalled("Microsoft Visual C++ 2013", ProgramVersion.x64));
        Console.ReadKey();
    }
}
}

  • Mit diesem Code kann ich Notepad++ 32bit auf meinem Computer erkennen, aber nicht Notepad++ 64bit auf einem anderen Computer. Übrigens ist der Code durch die Nestling-Methode wirklich schwer lesbar

    – Willkommen

    17. September 2019 um 20:02 Uhr

  • ok, grund gefunden. 32-Bit-Anwendung benötigt eine Problemumgehung für die Suche nach installierten 64-Bit-Anwendungen

    – Willkommen

    18. September 2019 um 17:34 Uhr

Die Lösung @Hyperion ist in Ordnung, aber sie hat einen Fehler, weil für 32-Bit-Konfigurationen. Es werden keine 64-Bit-Register zurückgegeben. Gehen Sie wie folgt vor, um 64-Bit-Register zu empfangen:

string registryKey = @"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall";
RegistryKey key64 = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry64);
RegistryKey key = key64.OpenSubKey(registryKey);

Benutzer-Avatar
Blaato

Die oben genannten Lösungen sind wirklich gut, aber manchmal müssen Sie überprüfen, ob das Produkt auch auf einem anderen Computer installiert ist. Es gibt also eine Version, die auf den obigen Lösungen von @Stellan Lindell und @Mroczny Arturek basiert

Diese Methode funktioniert für den lokalen Computer und auch für den Remote-Computer.

    public static bool IsSoftwareInstalled(string softwareName, string remoteMachine = null, StringComparison strComparison = StringComparison.Ordinal)
    {
        string uninstallRegKey = @"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall";

        RegistryView[] enumValues = (RegistryView[])Enum.GetValues(typeof(RegistryView));

        //Starts from 1, because first one is Default, so we dont need it...
        for (int i = 1; i < enumValues.Length; i++)
        {
            //This one key is all what we need, because RegView will do the rest for us
            using (RegistryKey key = (string.IsNullOrWhiteSpace(remoteMachine))
                ? RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, enumValues[i]).OpenSubKey(uninstallRegKey)
                : RegistryKey.OpenRemoteBaseKey(RegistryHive.LocalMachine, remoteMachine, enumValues[i]).OpenSubKey(uninstallRegKey))
            {
                if (key != null)
                {
                    if (key.GetSubKeyNames()
                        .Select(keyName => key.OpenSubKey(keyName))
                        .Select(subKey => subKey.GetValue("DisplayName") as string)
                        //SomeTimes we really need the case sensitive/insensitive option...
                        .Any(displayName => displayName != null && displayName.IndexOf(softwareName, strComparison) >= 0))
                    { return true; }
                }
            }
        }

        return false;
    }

Die Registrierungsversion ist nur eine von zwei Standardoptionen. Eine andere Option ist die Verwendung von WMI, aber die Registrierungsversion ist aufgrund der Leistung viel besser, also nehmen Sie nur WMI als Alternative.

    //This one does't have a case sensitive/insesitive option, but if you need it, just don't use LIKE %softwareName%
    //and get all products (SELECT Name FROM Win32_Product). After that just go trough the result and compare...
    public static bool IsSoftwareInstalledWMI(string softwareName, string remoteMachine = null)
    {
        string wmiPath = (!string.IsNullOrEmpty(remoteMachine))
                            ? @"\\" + remoteMachine + @"\root\cimv2"
                            : @"\\" + Environment.MachineName + @"\root\cimv2";

        SelectQuery select = new SelectQuery(string.Format("SELECT * FROM Win32_Product WHERE Name LIKE \"%{0}%\"", softwareName));

        if (SelectStringsFromWMI(select, new ManagementScope(wmiPath)).Count > 0) { return true; }

        return false;
    }

Es gibt meine SelectStringsFromWMI-Methode, aber Sie können dies selbst tun, dies ist kein wichtiger Teil dieser Lösung. Aber falls es dich interessiert, hier ist es…

    public static List<Dictionary<string, string>> SelectStringsFromWMI(SelectQuery select, ManagementScope wmiScope)
    {
        List<Dictionary<string, string>> result = new List<Dictionary<string, string>>();
        using (ManagementObjectSearcher searcher = new ManagementObjectSearcher(wmiScope, select))
        {
            using (ManagementObjectCollection objectCollection = searcher.Get())
            {
                foreach (ManagementObject managementObject in objectCollection)
                {
                    //With every new object we add new Dictionary
                    result.Add(new Dictionary<string, string>());
                    foreach (PropertyData property in managementObject.Properties)
                    {
                        //Always add data to newest Dictionary
                        result.Last().Add(property.Name, property.Value?.ToString());
                    }
                }

                return result;
            }
        }
    }

!!AKTUALISIEREN!!

Aufgrund der wirklich schlechten Leistung gibt es eine weitere Verbesserung. Holen Sie sich einfach die Werte asynchron.

public static bool IsSoftwareInstalled(string softwareName, string remoteMachine = null, StringComparison strComparison = StringComparison.Ordinal)
{
    string uninstallRegKey = @"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall";

    RegistryView[] enumValues = (RegistryView[])Enum.GetValues(typeof(RegistryView));

    //Starts from 1, because first one is Default, so we dont need it...
    for (int i = 1; i < enumValues.Length; i++)
    {
        //This one key is all what we need, because RegView will do the rest for us
        using (RegistryKey regKey = (string.IsNullOrWhiteSpace(remoteMachine))
                    ? RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, enumValues[i]).OpenSubKey(uninstallRegKey)
                    : RegistryKey.OpenRemoteBaseKey(RegistryHive.LocalMachine, remoteMachine, enumValues[i]).OpenSubKey(uninstallRegKey))
        {
              if (SearchSubKeysForValue(regKey, "DisplayName", softwareName, strComparison).Result)
              { return true; }
        }
    }

    return false;
}

Und die SearchSubKeysForValue-Methode (kann als Erweiterungsmethode erstellt werden):

    public static async Task<bool> SearchSubKeysForValue(RegistryKey regKey, string valueName, string searchedValue, StringComparison strComparison = StringComparison.Ordinal)
    {
        bool result = false;
        string[] subKeysNames = regKey.GetSubKeyNames();
        List<Task<bool>> tasks = new List<Task<bool>>();

        for (int i = 0; i < subKeysNames.Length - 1; i++)
        {
            //We have to save current value for i, because we cannot use it in async task due to changed values for it during foor loop
            string subKeyName = subKeysNames[i];
            tasks.Add(Task.Run(() =>
            {
                string value = regKey.OpenSubKey(subKeyName)?.GetValue(valueName)?.ToString() ?? null;
                return (value != null && value.IndexOf(searchedValue, strComparison) >= 0);
            }));
        }

        bool[] results = await Task.WhenAll(tasks).ConfigureAwait(false);
        result = results.Contains(true);

        return result;
    }

  • Die ursprüngliche Frage hatte nichts mit entfernten Maschinen zu tun

    – Hyperions

    20. September 2018 um 14:19 Uhr

  • @Faded, aber Sie können diese Lösung für lokale und sogar Remote-Computer verwenden. Ja, dies ist eine Lösung für Ihre Antwort mit einigen Verbesserungen. Daher verstehe ich die Ablehnung nicht.

    – Blato

    21. September 2018 um 6:18 Uhr

  • @Faded vielleicht wirst du diese aktualisierte Verbesserung mehr zu schätzen wissen … 🙂

    – Blato

    25. September 2018 um 6:52 Uhr

Benutzer-Avatar
Willkommen

Ich habe die Lösungen hier ausprobiert, aber sie haben in einigen Fällen nicht funktioniert. Der Grund war, dass mein Programm 32 Bit ist und auf 64 Bit Windows läuft. Mit den hier geposteten Lösungen a 32-Bit-Prozess kann nicht prüfen, ob eine 64-Bit-Anwendung installiert ist.

So greifen Sie mit einem 32-Bit-Prozess auf die 64-Bit-Registrierung zu

RegistryKey.OpenBaseKey

Ich habe die Lösungen hier geändert, um eine funktionierende Lösung für dieses Problem zu erhalten:

Anwendungsbeispiel

 Console.WriteLine(IsSoftwareInstalled("Notepad++"));

Code

    public static bool IsSoftwareInstalled(string softwareName)
    {
        var registryUninstallPath                = @"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall";
        var registryUninstallPathFor32BitOn64Bit = @"SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall";

        if (Is32BitWindows())
            return IsSoftwareInstalled(softwareName, RegistryView.Registry32, registryUninstallPath);

        var is64BitSoftwareInstalled = IsSoftwareInstalled(softwareName, RegistryView.Registry64, registryUninstallPath);
        var is32BitSoftwareInstalled = IsSoftwareInstalled(softwareName, RegistryView.Registry64, registryUninstallPathFor32BitOn64Bit);
        return is64BitSoftwareInstalled || is32BitSoftwareInstalled;
    }

    private static bool Is32BitWindows() => Environment.Is64BitOperatingSystem == false;

    private static bool IsSoftwareInstalled(string softwareName, RegistryView registryView, string installedProgrammsPath)
    {
        var uninstallKey = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, registryView)
                                              .OpenSubKey(installedProgrammsPath);

        if (uninstallKey == null)
            return false;

        return uninstallKey.GetSubKeyNames()
                           .Select(installedSoftwareString => uninstallKey.OpenSubKey(installedSoftwareString))
                           .Select(installedSoftwareKey => installedSoftwareKey.GetValue("DisplayName") as string)
                           .Any(installedSoftwareName => installedSoftwareName != null && installedSoftwareName.Contains(softwareName));
    }

  • Die ursprüngliche Frage hatte nichts mit entfernten Maschinen zu tun

    – Hyperions

    20. September 2018 um 14:19 Uhr

  • @Faded, aber Sie können diese Lösung für lokale und sogar Remote-Computer verwenden. Ja, dies ist eine Lösung für Ihre Antwort mit einigen Verbesserungen. Daher verstehe ich die Ablehnung nicht.

    – Blato

    21. September 2018 um 6:18 Uhr

  • @Faded vielleicht wirst du diese aktualisierte Verbesserung mehr zu schätzen wissen … 🙂

    – Blato

    25. September 2018 um 6:52 Uhr

Benutzer-Avatar
jerryurena

Hier ist meine Version für 64 Bit

  public static string[] checkInstalled(string findByName)
    {
        string[] info = new string[3];

        string registryKey = @"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall";

        //64 bits computer
        RegistryKey key64 = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry64);
        RegistryKey key = key64.OpenSubKey(registryKey);

        if (key != null)
        {
            foreach (RegistryKey subkey in key.GetSubKeyNames().Select(keyName => key.OpenSubKey(keyName)))
            {
                string displayName = subkey.GetValue("DisplayName") as string;
                if (displayName != null && displayName.Contains(findByName))
                {
                    info[0] = displayName;

                    info[1] = subkey.GetValue("InstallLocation").ToString();

                    info[2] = subkey.GetValue("Version").ToString();
                }
            }

            key.Close();
        }

        return info;
    }

Sie können diese Methode so aufrufen

string[] JavaVersion = Software.checkInstalled("Java(TM) SE Development Kit");

Wenn das Array leer ist, wurde keine Installation gefunden. Wenn es nicht leer ist, erhalten Sie den ursprünglichen Namen, den relativen Pfad und den Speicherort, was in den meisten Fällen alles ist, was wir erhalten möchten.

1310980cookie-checkÜberprüfen Sie, ob die Anwendung in der Registrierung installiert ist

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy