Laden...

Softwareversion (aus Registry) wird im Release-Modus erkannt, im Debug-Modus nicht

Erstellt von LittleTester vor 2 Jahren Letzter Beitrag vor 2 Jahren 495 Views
L
LittleTester Themenstarter:in
158 Beiträge seit 2019
vor 2 Jahren
Softwareversion (aus Registry) wird im Release-Modus erkannt, im Debug-Modus nicht

Wenn ich folgenden Code verwende, um den Versionsstand einer Software (in dem Fall Dell Command Update) auszulesen erhalte ich im Debug-Modus die Meldung, dass die Software nicht installiert sei. Im Release-Modus wird hingegen die Installation, bzw. die Version erkannt. Ich verwende die gleiche Methodik um auch andere Softwareversionen zu erfragen und das klappt sonnst ganz gut. Hier der Code der Problemsoftware:


            // Dell Command Update Version ermitteln
            try {
                RegistryKey findDCU = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Dell\UpdateService\Clients\CommandUpdate\Preferences\Settings");
                if (findDCU != null) {
                    Object dcuVersion = findDCU.GetValue("ProductVersion");
                    if (dcuVersion != null) {
                        string version = findDCU.GetValue("ProductVersion").ToString();
                        softwareDellCommandUpdate = version;
                    } else {
                        softwareDellCommandUpdate = "Nicht installiert";
                    }
                } else {
                    softwareDellCommandUpdate = "Nicht installiert";
                }
            } catch (Exception) {
                MessageBox.Show("Systeminfo hat ein Problem im Abschnitt Dell Command Update.");
            }

Und hier mal der Code, der sowohl im Debug-Modus, als auch im Release-Modus funktioniert.


            // MS-Teams Version ermitteln
            try {
                RegistryKey findMsTeams = Registry.CurrentUser.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Teams");
                if (findMsTeams != null) {
                    Object msteamsVersion = findMsTeams.GetValue("DisplayVersion");
                    if (msteamsVersion != null) {
                        string version = findMsTeams.GetValue("DisplayVersion").ToString();
                        softwareMsTeams = version.Substring(0, 5);
                    } else {
                        softwareMsTeams = "Nicht installiert";
                    }
                } else {
                    softwareMsTeams = "Nicht installiert";
                }
            } catch (Exception) {
                MessageBox.Show("Systeminfo hat ein Problem im Abschnitt MS-Teams.");
            }

Jemand eine Idee, warum das so sein könnte?

IDE: Visual Studio 2022
Sofern nicht anders genannt basieren meine Projekte auf C# und .net 6

4.939 Beiträge seit 2008
vor 2 Jahren

Dann debugge doch mal (da du ja zwei Pfade mit "Nicht installiert" hast)...

Läßt du denn VS und die Anwendung unter demselben User laufen (bzw. mit/ohne Admin-Rechten) - wegen LocalMachine vs. CurrentUser?

Und warum rufst du jeweils zweimal GetValue auf, anstatt einfach


object dcuVersion = findDCU.GetValue("ProductVersion");
if (dcuVersion != null)
       softwareDellCommandUpdate = dcuVersion.ToString();

?

L
LittleTester Themenstarter:in
158 Beiträge seit 2019
vor 2 Jahren

Danke für deine Antwort:

Also das Programm teste ich auf meinem Geschäftsrechner mit Benutzerrechten (keine Adminrechte), so wie das nachher auch laufen wird.
Ich teste die Release und Debug-Variante immer mit dem gleichen Benutzer.

Das mit der Variable habe ich korrigiert. Hast natürlich vollkommen Recht. Danke für diesen Hinweis.
Ich habe die Abfrage angepasst:


            // Dell Command Update Version ermitteln
            try 
            {
                RegistryKey findDCU = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Dell\UpdateService\Clients\CommandUpdate\Preferences\Settings");
                if (findDCU != null)
                {
                    Object dcuVersion = findDCU.GetValue("ProductVersion");
                    if (dcuVersion != null)
                    {
                        string version = dcuVersion.ToString();
                        softwareDellCommandUpdate = version;
                    } 
                    else
                    {
                        softwareDellCommandUpdate = "Version unbekannt";
                    }
                } 
                else
                {
                    softwareDellCommandUpdate = "Nicht installiert";
                }
            } 
            catch (Exception)
            {
                MessageBox.Show("Systeminventory hat ein Problem im Abschnitt Dell Command Update.");
            }

Im Debug-Modus steigt er bei "Nicht installiert" aus, scheint also ein Problem mit dem Pfad zu haben, aber warum? Was macht der Debug-Modus anders als der Release-Modus?

IDE: Visual Studio 2022
Sofern nicht anders genannt basieren meine Projekte auf C# und .net 6

L
LittleTester Themenstarter:in
158 Beiträge seit 2019
vor 2 Jahren

Mist, paar Sekunden zu spät zum Editieren:

Ich habe das Programm gerade auf einem Rechner laufen lassen, wo ESET installiert ist. Auch hier das Problem, dass es im Debug-Modus nicht erkannt wird, im Release-Modus schon.
Der Pfad lautet:

Registry.LocalMachine.OpenSubKey(@"SOFTWARE\ESET\ESET Security\CurrentVersion\Info");

Ich bin mit Adminrechnten auf den Rechner, weil ich da heute eh ne Fernwartung drauf mache. Es macht also keinen Unterschied, ob das Programm mit oder ohne Adminrechten läuft.

IDE: Visual Studio 2022
Sofern nicht anders genannt basieren meine Projekte auf C# und .net 6

D
261 Beiträge seit 2015
vor 2 Jahren

Hast du verschiedene Plattformen (x86 vs x64) in der Debug und Release Konfiguration?

Edit: siehe https://stackoverflow.com/a/3872535/1627022

16.835 Beiträge seit 2008
vor 2 Jahren

Den einzigen Unterschied, den es beim Umgang mit der Registry prinzipiell gibt, taucht bei x64 und x86 Prozessen auf.
Habe noch nie gehört, gelesen oder gesehen, dass es beim Compile Mode einen Unterschied geben sollte und wüsste auf Anhieb auch keinen technischen Umstand, der das begründen würde.
Finde auf Anhieb dazu auch nichts in der Doku, daher bezweifle ich einfach mal, dass der Fehler so existiert, wie er hier beschrieben wird.

L
LittleTester Themenstarter:in
158 Beiträge seit 2019
vor 2 Jahren

dannoe hatte Recht. Habe da wohl bissel rumgespielt gehabt. Danke dir.

Als ich die Zielplattform "Any CPU" umgestellt habe werden die beiden Softwares nicht mehr erkannt. Als ich es auf x64 umgestellt habe hingegen schon.

Ich habe es jetzt für den Debug-Modus und Release-Modus auf x64 gestellt. x86 ist ja eh veraltet und x86-Betriebssysteme werden bei uns nicht mehr eingesetzt. Oder spricht was dagegen die Architektur auf x64 umzustellen?

IDE: Visual Studio 2022
Sofern nicht anders genannt basieren meine Projekte auf C# und .net 6

16.835 Beiträge seit 2008
vor 2 Jahren

x86 ist ja eh veraltet und x86-Betriebssysteme werden bei uns nicht mehr eingesetzt.

Nimm doch mal den Tipp zu Herzen, der Dir schon paar Mal gegeben wurde, und werf bei Unklarheiten einen Blick in die Doku. Hier wieder so ein Fall 😉C# Compiler Options - Output options
Die Bitness (x86 vs x64) hat primär nichts mit dem Betriebssystem zutun, sondern mit dem Prozess.
https://www.hanselman.com/blog/back-to-basics-32bit-and-64bit-confusion-around-x86-and-x64-and-the-net-framework-and-clr

Du kannst problemlos einen x86 Prozess auf einem x64 System ausführen, was bezogen auf den Fall sogar durchaus oft bessere Weg ist; aber nicht umgekehrt.
In .NET ist dafür maßgeblich auch die Runtime verantwortlich, die in der jeweiligen Bitness installiert sein muss.

Es gibt viele Gründe, warum Du x86 bevorzugen solltest, aber ebenso viele Gründe, warum x64 der bessere Weg sein kann.
Kommt auf die Anforderungen und auf die Zielumgebung an.

ASP.NET Core sollte man auf Windows Systemen als 32 Bit Prozess laufen lassen; unter Linux ist der empfohlene Weg x64.
Auf Windows ist hier die Kompatibilität zu x86 einfach (noch) besser (Systemressourcen, IIS..); .NET wird auf Linux nur als x64 angeboten.
Daher nein: x86 ist bei weitem keine veraltete Architektur.

Und ja, mit/durch WOW64 ist es für .NET Anwendung wichtig, mit welcher Bitness der Prozess ausgeführt wird, um auf die Registry zuzugreifen.
WOW ist ein "Prozess Emulator" unter Windows, damals von 16 auf 32 Bit, heute mit WOW64 eben von 32 auf 64 Bit. Dank dem Ding kannst Du von x64 Prozessen zB auf x86 Registry zugreifen

Früher war das Standard Template AnyCPU, mit VS 2010 wars dann x86 und seit ich glaube .NET 4 oder .NET 4.5 ist es AnyCPU, wobei unter der Haube "Any CPU x86 prefered" ausgeführt wird. Du hast hier in den Projekteinstellungen die Möglichkeit entsprechend das Platform Target und den Prefer zu konfigurieren.
D.h. mit AnyCPU wurde, sofern möglich, der Prozess als x86 ausgeführt. Bin mir ehrlich gesagt gar nicht so sicher, ob sich hier was mit .NET Core / .NET 5 geändert hat.

L
LittleTester Themenstarter:in
158 Beiträge seit 2019
vor 2 Jahren

Danke für deine Hinweise Abt. Ich habe das Projekt wieder umgestellt. Das "Problem" ist wohl, dass beim Aufruf von regedit unter Windows die x64-Version genommen wird, während unter Visual Studio (zumindest C#) standardmäßig die x86-Version genommen wird. Da können die Pfade dann manchmal nicht identisch sein. (Quelle)

Ich habe mir jetzt so beholfen, dass ich folgenden Code verwende, wenn ich die explizit die x64-Version der Registry haben will. Ich hoffe das findet eure Zustimmung.


                RegistryKey findeEintrag = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry64).OpenSubKey(@"Pfad");

IDE: Visual Studio 2022
Sofern nicht anders genannt basieren meine Projekte auf C# und .net 6