Ergebnis 1 bis 14 von 14

Thema: [C#] Installierte Programmversionen ermitteln

  1. #1
    Der ohne Avatar
    Registriert seit
    Jul 2013
    Beiträge
    1.095
    ngb:news Artikel
    1

    [C#] Installierte Programmversionen ermitteln

    Ich versuche von ausgewählten Programmen die wichtig sind die Versionsnummer zu ermitteln.

    Mittels PowerShell kann ich beispielsweise die Office-Version wie folgt ermitteln:
    Code (PowerShell):
    1.  Get-WmiObject win32_product | where{$_.Name -like "Microsoft Office *"} | select Name,Version
    Klappt. PowerShell sagt, dass Microsoft Office Professional Plus 2016 in Version 16.0.4266.1001 bei mir installiert ist. Stimmt.


    Nun wollte ich das Ganze in C#-Code übertragen, aber die Abfrage ist immer ungültig. Was habe ich verbockt? Ich hoffe ihr könnt mir helfen.
    Code (C#):
    1.             // Office Version ermitteln
    2.             try
    3.             {
    4.                 ManagementObjectCollection motReturn;
    5.                 ManagementObjectSearcher motSearch;
    6.  
    7.                 motSearch = new ManagementObjectSearcher("Select * from Win32_Product where Name like 'Microsoft Office * '");
    8.  
    9.                 motReturn = motSearch.Get();
    10.                 foreach (ManagementObject mo in motReturn)
    11.                 {
    12.                     label22.Text = mo["Version"].ToString();
    13.                 }
    14.             }
    15.             catch (Exception ex)
    16.             {
    17.                 MessageBox.Show(ex.Message);
    18.             }
    Geändert von Cyperfriend (03.02.21 um 22:57 Uhr)

  2. #2
    Boomer ♪♪♫♪♫♫♪

    News-Redakteur

    Avatar von KaPiTN
    Registriert seit
    Jul 2013
    Beiträge
    24.229
    ngb:news Artikel
    34

    Re: [C#] Installierte Programmversionen ermitteln

    label22.Text wird bei foreeach immer nur das letzte Element aus motReturn enthalten.

    Aber mal eine ketzerische Frage. Kann die 7.5 schon vorher zugewiesen worden sein?

    Ich versteh überhaupt nicht, wie da bei Dir ein Ergebnis kommt. Ich habe den Code für // Office Version ermitteln auf 2 Rechnern ausgeführt, war zwischenzeitlich weg und nach fast 20 Minuten hatte die Abfrage immer noch kein Ergebnis.
    J'irai pisser sur votre bombes
    You can educate a fool, but you cannot make him think

  3. #3
    Der ohne Avatar

    (Threadstarter)


    Registriert seit
    Jul 2013
    Beiträge
    1.095
    ngb:news Artikel
    1

    Re: [C#] Installierte Programmversionen ermitteln

    Ja, da habe ich offenbar den falschen Code gepostet. Kommt davon, wenn man das Projekt auf zwei Rechnern (einmal Remote) testen möchte

    Der oben genannte Code macht tatsächlich einfach nix. Wenn man die Abfrage etwas umbaut bekommt man die MessageBox "Die Abfrage ist ungültig"
    Code (C#):
    1. motSearch = new ManagementObjectSearcher("Select * from Win32_Product where Name like Office ");
    Code (C#):
    1. motSearch = new ManagementObjectSearcher("Select * from Win32_Product where Name = Office ");
    Es hat sich dann aber noch herausgestellt, dass es sehr schwer zu unterscheiden ist, ob Office 2016/2019 oder gar Office 365 installiert ist, denn Office 365 wird in der Systemsteuerung / unter Apps als Microsoft 365 Apps for Enterprice gelistet - und das in Version 16.xxx. Die Abfrage über die Version beispielsweise der WINWORD.exe wie auf stackoverflow vorgeschlagen bringt also nichts, weil Office 2016/2019/365 jeweils als Version 16 gekennzeichnet sind.

    Vielleicht noch wichtig zu wissen: Am Ende möchte ich die Programmversionen von Citrix Workspace, Starface UCC-Client und F-Secure. Ich schätze aber mal die grundsätzliche Abfragesyntax bleibt gleich.
    Geändert von Cyperfriend (04.02.21 um 17:44 Uhr)

  4. #4
    Boomer ♪♪♫♪♫♫♪

    News-Redakteur

    Avatar von KaPiTN
    Registriert seit
    Jul 2013
    Beiträge
    24.229
    ngb:news Artikel
    34

    Re: [C#] Installierte Programmversionen ermitteln

    Kannst Du die Versionen nicht der registry entnehmen?
    J'irai pisser sur votre bombes
    You can educate a fool, but you cannot make him think

  5. #5
    Der ohne Avatar

    (Threadstarter)


    Registriert seit
    Jul 2013
    Beiträge
    1.095
    ngb:news Artikel
    1

    Re: [C#] Installierte Programmversionen ermitteln

    Registrypfade können sich mit jeder Version ändern. Über WMI erhalte ich immer die Versionnummer.

    Was ich etwas nervig finde ist, dass die WMI-Abfrage furchtbar lange dauert, aber ich schätze damit muss man leben.

    Ich habe es mittlerweile auch hinbekommen. Ich bin leider übelst darauf reingefallen, dass in C# ein %, anstatt eines * verwendet werden muss. Das hat Zeit gekostet. Der Code sieht jetzt so aus:

    Code (C#):
    1.             // Office Version ermitteln
    2.             try
    3.             {
    4.                 searcher = new ManagementObjectSearcher("Select * from Win32_Product where Name like 'Microsoft Office Professional%'");
    5.                 foreach (ManagementObject ggg in searcher.Get())
    6.                 {
    7.                     label22.Text = ggg["Name"].ToString() + " " + ggg["Version"].ToString();
    8.                 }
    9.             }
    10.             catch (Exception ex)
    11.             {
    12.                 MessageBox.Show(ex.Message);
    13.             }
    Jetzt brauche ich nur noch den Code, dass falls das gesuchte Programm nicht gefunden wird, also kein Ergebnis zurückgeliefert wird. Kann mir da bitte jemand behilflich sein?
    Geändert von Cyperfriend (05.02.21 um 21:28 Uhr)

  6. #6
    Boomer ♪♪♫♪♫♫♪

    News-Redakteur

    Avatar von KaPiTN
    Registriert seit
    Jul 2013
    Beiträge
    24.229
    ngb:news Artikel
    34

    Re: [C#] Installierte Programmversionen ermitteln

    Bei keinem Ergebnis wäre searcher.Get().Count =0. Das könntest Du abfragen

    Ich bin jetzt nicht in der Materie drin, aber mal ein paar Anmerkungen.

    Unabhängig davon, daß mein Rechner mal neu gestartet werden sollte, so braucht die Abfrage bei mir über 2 Minuten.

    Ich hatte bereits erwähnt, daß Du bei foreach nur das letzte Element aus searcher.Get() im label22 sehen wirst, weil das ja immer überschrieben wird.
    Und da steht möglicherweise einiges drin.

    Ich habe hier kein MS Office extra zu Windows 10 installiert, dennoch habe ich da 13 Elemente in der Ergebnismenge.Wahrscheinlich kostenlose Webversionen von Word, Excel und PowerPoint und wer weiß noch etwas.(?)
    J'irai pisser sur votre bombes
    You can educate a fool, but you cannot make him think

  7. #7
    Der ohne Avatar

    (Threadstarter)


    Registriert seit
    Jul 2013
    Beiträge
    1.095
    ngb:news Artikel
    1

    Re: [C#] Installierte Programmversionen ermitteln

    Ja, deswegen habe ich die Abfrage angepasst auf "Microsoft Office Professional%"

    Jetzt muss da nur irgendwie noch ne Abfrage rein in der Art
    Code (C#):
    1. Name like "Microsoft Office Professional%" or Name like "Microsoft 365 Apps%"){
    2. if(Name == "Microsoft Office Professional%"
    3. variable = "Office 2016";
    4. if(Name == "Microsoft 365 Apps%")
    5. variable = "Office 365";
    6.  
    Kann mir bitte wer sagen, wie man das umsetzt?

  8. #8
    Zeitreisender

    Administrator

    Avatar von drfuture
    Registriert seit
    Jul 2013
    Ort
    in der Zukunft
    Beiträge
    7.204
    ngb:news Artikel
    18

    Re: [C#] Installierte Programmversionen ermitteln

    Die Abfrage auf Win32_Product geht auf div. stellen in der Registry. Die Quelle ist per WMI also schon die Registry, aber ist so etwas universeller zu benutzen da sonst im Programm nach 32/64bit und bei zukünftigen Versionen im Zweifel auf neue Pfade geachtet werden müsste. Die WIM Aufrufe funktionieren schon sehr lange.

    Du kannst auf die Klasse Win32Reg_AddRemovePrograms wechseln. Diese ist deutlich schneller und sollte für deinen Zweck auch passen. Zusätzlich würde die die abgefragten Werte auf das anpassen was du benötigst (Name, Version?)

    Mit Office hast du dir wirklich ein Paradebeispiel ausgesucht ;D
    Da du vermutlich so oder so eine Abfrage über AddRemovePrograms wegen div. anderen Anwendungen machst würde ich hier im Ergebnis schauen ob ein Office installiert ist.

    Wenn ja:
    Schaue im Dateisystem unter Environment-Variable "Programfiles" > \Microsoft Office\* und Environment-Variable "ProgramFiles(x86)" > Microsoft Office\* eine der Office-Programm-Dateien finde (winword.exe, excel.exe,outlook.exe powerpnt.exe) sobald 1. gefunden > abbruch (Oder, da man mehrere Office-Versionen parallel installieren kann weiter suchen) und jeweils von jeder gefunden .exe die Version auslesen.

    Office 2016 und Office 2019 sind im großen und Ganzen nur Snapshots von Office365 abzüglich einer Hand voll Feature die nur mit Online-Account funktionieren (z.B. Übersetzung von Folien in Powerpoint).
    Daher sind hier die Build-Versionen ein Marker (Auch für Office-365).

    https://docs.microsoft.com/de-de/off...5-apps-by-date
    https://docs.microsoft.com/de-de/off...ry-office-2019

    @Problem mit der Abfrage:
    Da du ja mehrere Anwendungen Prüfen möchtest und die Abfrage a) Zeit braucht und sich b) in den wenigen Sekunden vermutlich nicht ändert würde ich einmal eine Abfrage über alles aus Win32Reg_AddRemovePrograms machen also

    Code (C#):
    1.             // Office Version ermitteln
    2.  
    3. public class AddRemovePrograms
    4. {
    5.     public string Publisher { get; set; }
    6.     public string DisplayName { get; set; }
    7.     public string Version { get; set; } //Hier könnte man überlegen einen Versions-Datentyp zu nehmen, leider halten sich aber nicht alle Softwarefirmen an eine passende Notation der Version)
    8. }
    9.  
    10.  
    11. List<AddRemovePrograms> AddRemoveProgramsItems = new List<AddRemovePrograms>();
    12.  
    13.             try
    14.             {
    15.                 searcher = new ManagementObjectSearcher("Select DisplayName, Publisher, Version from Win32Reg_AddRemovePrograms'");
    16.                 foreach (ManagementObject ggg in searcher.Get())
    17.                 {
    18. AddRemoveProgramsItems.Add(new AddRemovePrograms{ Publisher = ggg["Publisher"].Tostring(), Displayname = ggg["DisplayName"].tostring(), Version = ggg["Version"].ToString() });
    19.  
    20.                 }
    21.             }
    22.             catch (Exception ex)
    23.             {
    24.                 MessageBox.Show(ex.Message);
    25.             }
    Und dann erst die Liste durchgehen und dort auf die jeweiligen Programmnamen suchen.
    |_|D *`~{ Ich kenne deine Zukunft }~´* |_|D

  9. #9
    Der ohne Avatar

    (Threadstarter)


    Registriert seit
    Jul 2013
    Beiträge
    1.095
    ngb:news Artikel
    1

    Re: [C#] Installierte Programmversionen ermitteln

    Ich habe Win32Reg_AddRemovePrograms ausprobiert. Office Professional Plus 2016 wird nicht gefunden. Auch Citrix Workspace wird nicht gelistet. Man kann das auch einfach kontrollieren in deman in die PowerShell "get-wmiobject -Class Win32Reg_AddRemovePrograms" eingibt. Bei meinem zweiten Arbeitgeber bekam ich ein Ergebnis. Hier bei mir zu Hause bekomme ich
    Get-WmiObject : Ungültige Klasse "Win32Reg_AddRemovePrograms"
    In Zeile:1 Zeichen:1
    + Get-WmiObject -Class Win32Reg_AddRemovePrograms
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : InvalidType: (:) [Get-WmiObject], ManagementException
    + FullyQualifiedErrorId : GetWMIManagementException,Microsoft.PowerShell.Commands.GetWmiObjectCommand
    Alles in allem scheint die Klasse aber nicht das zu bieten, was ich brauche.

    Bei Office geht es mir vornehmlich darum die Lizenz zuordnen zu können. Office 365 bekommen wir von einer uns übergeordneten Organisation und müssen keine Lizenzkosten für bezahlen.
    Office Professional Plus 2016 müssen wir hingegen selbst beschaffen und Lizenzgebühren bezahlen.
    Deswegen brauche ich die klare Unterscheidung.

    Ich habe auch schon im nuget-Marketplace geguckt, ob ich dort vielleicht was finde, was die Auflistung der installierten Programme einfacher und schneller macht. Ich konnte aber leider nichts finden. Habt ihr da vielleicht eine Idee?

  10. #10
    Zeitreisender

    Administrator

    Avatar von drfuture
    Registriert seit
    Jul 2013
    Ort
    in der Zukunft
    Beiträge
    7.204
    ngb:news Artikel
    18

    Re: [C#] Installierte Programmversionen ermitteln

    Man merke:
    Es kommt auf die Testumgebung an wenn man etwas schreibt.
    Hatte das ja vorher getestet - bei mir gabs die auch > daheim nicht... > recherge:
    Die gehört zum Microsoft ConfigManager - der muss installiert sein... das trifft in der Firma zu, zu Hause nicht.

    Wenn das bei dir aber bei der einen Firma funktioniert - dann ist der dort wohl installiert?
    Gibt es Dienste die mit sms... anfangen?

    Dann hättest du dort schon mehr als genug Infos in dessen Inventuren. Die Frage ist ob du dort dann Zugriff bekommst.
    Nur im anderen Laden bringt dir das nichts.

    Die Klasse kann als 32-bit und 64bit prozess aufgerufen werden und gibt jeweils das andere Ergebnis.

    Aber die Office-Version kannst du eben anhand der Exe auslesen.
    Wenn du eh weißt wohin die jeweiligen Programme installiert werden - auch bei Citrix - könnte man, statt alle Programme einzulesen in der Registry in den passenden Bereichen nach Citrix, Microsoft etc. direkt suchen. Das ist dann weit weniger Dynamisch aber dafür eben deutlich performanter.
    |_|D *`~{ Ich kenne deine Zukunft }~´* |_|D

  11. #11
    Der ohne Avatar

    (Threadstarter)


    Registriert seit
    Jul 2013
    Beiträge
    1.095
    ngb:news Artikel
    1

    Re: [C#] Installierte Programmversionen ermitteln

    Naja das Tool programmiere ich für meinen ersten Arbeitgeber und dort gibt es 13 Dienststellen mit ganz vielen Arbeitsgruppenrechnern und Laptops. Ich bin da nur gerade im Homeoffice und bei meinem zweiten Arbeitgeber habe ich zwischendrin die Möglichkeit an dem Programm weiter zu arbeiten, bzw. auch zu testen.
    Also nix SCCM

  12. #12
    Der ohne Avatar

    (Threadstarter)


    Registriert seit
    Jul 2013
    Beiträge
    1.095
    ngb:news Artikel
    1

    Re: [C#] Installierte Programmversionen ermitteln

    Leider scheint es über WMI / Win32_Product nicht möglich zu sein zwischen Office Pro und Office 365 zu unterscheiden. Also der Weg über die Registry.
    Anbei der Code. Hoffe er stößt auf Zustimmung:
    Code (C#):
    1.         string whichOffice;
    2.             // Office Version ermitteln
    3.             try {
    4.                 // Suche nach Office 365
    5.                 string findOffice365 = @"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\O365ProPlusRetail - de-de";
    6.                 RegistryKey office365Key = Microsoft.Win32.Registry.LocalMachine;
    7.                 RegistryKey office365Subkey = office365Key.OpenSubKey(findOffice365);
    8.  
    9.                 if (office365Subkey != null) {
    10.                     string office365Name = office365Subkey.GetValue("DisplayName").ToString();
    11.                     if (office365Name.Trim().Contains("Microsoft 365 Apps for Enterprise")) {
    12.                         whichOffice = "Office 365";
    13.                     }
    14.                 } else { }
    15.  
    16.                 // Suche nach Office 2016
    17.                 string findOfficePro = @"SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\Office16.PROPLUS";
    18.                 RegistryKey officeProKey = Microsoft.Win32.Registry.LocalMachine;
    19.                 RegistryKey officeProSubkey = officeProKey.OpenSubKey(findOfficePro);
    20.  
    21.                 if (officeProSubkey != null) {
    22.                     string officeProName = officeProSubkey.GetValue("DisplayName").ToString();
    23.                     if (officeProName.Trim().Contains("Microsoft Office Professional Plus 2016")) {
    24.                         whichOffice = "Office Professional Plus 2016";
    25.                     }
    26.                 }  else { }
    27.             }
    28.             catch (Exception ex) {
    29.                 MessageBox.Show(ex.Message);
    30.             }
    31.  
    32.             if (whichOffice == null) {
    33.                 lblSoftwareOffice.Text = "Nicht installiert";
    34.             } else {
    35.                 lblSoftwareOffice.Text = whichOffice.ToString();
    36.             }

  13. #13
    Der ohne Avatar

    (Threadstarter)


    Registriert seit
    Jul 2013
    Beiträge
    1.095
    ngb:news Artikel
    1

    Re: [C#] Installierte Programmversionen ermitteln

    Ich habe den Code nochmals überarbeitet. Eigentlich möchte ich prüfen, ob ein Registry-Pfad überhaupt existiert. Die Suche danach ist aber irgendwie die Suche nach der Nadel im Heuhaufen. Ich konnte aber in dem Fall die Abfrage, welche Office-Version vorhanden ist vereinfachen. Eure Meinung? Was ist besser? Wie sollte es aussehen?

    Edit: Achja. Wie muss ich vorgehen sollten beide Office-Versionen gefunden werden? (Eigentlich nicht möglich, aber zumindest in der Theorie möglich.)
    Code (C#):
    1.         string whichOffice;
    2.             // Office Version ermitteln
    3.             try {
    4.                 // Suche nach Office 365
    5.                 var findOffice365 = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\O365ProPlusRetail - de-de");
    6.                 if (findOffice365 == null) {
    7.                     MessageBox.Show("Kein Office 365");
    8.                 } else {
    9.                     whichOffice = "Office 365";
    10.                 }
    11.  
    12.                 // Suche nach Office 2016
    13.                 var findOfficePro = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\Office16.PROPLUS");
    14.                 if (findOfficePro == null) {
    15.                     MessageBox.Show("Kein Office Pro");
    16.                 }  else {
    17.                     whichOffice = "Office Professional Plus 2016";
    18.                 }
    19.             }
    20.             catch (Exception ex)  {
    21.                 MessageBox.Show(ex.Message);
    22.             }
    23.  
    24.             if (whichOffice == null) {
    25.                 lblSoftwareOffice.Text = "Nicht installiert";
    26.             } else {
    27.                 lblSoftwareOffice.Text = whichOffice.ToString();
    28.             }
    Geändert von Cyperfriend (25.02.21 um 22:05 Uhr)

  14. #14
    Zeitreisender

    Administrator

    Avatar von drfuture
    Registriert seit
    Jul 2013
    Ort
    in der Zukunft
    Beiträge
    7.204
    ngb:news Artikel
    18

    Re: [C#] Installierte Programmversionen ermitteln

    So unrealistisch ist das gar nicht das er beide findet.
    z.B. ist die letzte OneNote Version die Version 2016 (Die komische neue App mal außen vor) - diese funktioniert auch mit aktuellem Office365. Dann würden wohl beide Versionen gefunden werden.

    Ich würde global ein Objekt "SoftwareFindings" erstellen mit den Eingenschaften "Hersteller, Produkt, Version, (evtl. Erkannt über Reg, Dateisystem etc.)"
    Und alle gefundenen Produkte - egal über welche "Suche" dort hinzufügen.

    Am Ende erfolgt dann die Ausgabe - in was auch immer... Tabelle, Listen, CSV, Excel, Datenbank

    Prüfen ob ein Pfad existert:
    Code (C#):
    1. using (var hklm = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry64))
    2. using (var key = hklm.OpenSubKey(@"SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\Office16.PROPLUS"))
    3. {
    4.     if (key == null)
    5.     {
    6.         // Doesn't exist...
    7.     }
    8.     else
    9.     {
    10.         // Exists...
    11.     }
    12. }
    Für diesen Beitrag bedankt sich Cyperfriend
    |_|D *`~{ Ich kenne deine Zukunft }~´* |_|D

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •