Benutzer mit den meisten Antworten
OpenSubKey

Frage
-
Guten Morgen,
in unserer App muss ein externes Java-Programm angestartet werden. Dazu schreibe ich OnFly eine kleine Batch mit dem Pfad zu Java (JavaHome). Der ändert sich nämlich sehr oft nach einem Java-Update. Ich suche also in der Registry nach der CurrentVersion und suche danach nach JavaHome. Das hat jahrelang auf allen Rechnern (WIN 7 und 10) funktioniert. Nun jedoch wurde ein Rechner neu aufgesetzt und es funktioniert auf diesem nicht.
Private Function WriteJavaCmd() As Boolean Dim jHomeDir As String = "" Dim jCurrVersion As String = "" Dim regPfad As String = "SOFTWARE\JavaSoft\Java Runtime Environment" If Microsoft.Win32.Registry.LocalMachine.OpenSubKey(regPfad) IsNot Nothing Then If Microsoft.Win32.Registry.LocalMachine.OpenSubKey(regPfad).GetValue("CurrentVersion") IsNot Nothing Then jCurrVersion = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(regPfad).GetValue("CurrentVersion").ToString regPfad = "SOFTWARE\JavaSoft\Java Runtime Environment\" & jCurrVersion If Microsoft.Win32.Registry.LocalMachine.OpenSubKey(regPfad).GetValue("JavaHome") IsNot Nothing Then jHomeDir = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(regPfad).GetValue("JavaHome").ToString End If End If End If If jHomeDir = "" Then regPfad = "SOFTWARE\WOW6432Node\JavaSoft\Java Runtime Environment" If Microsoft.Win32.Registry.LocalMachine.OpenSubKey(regPfad) IsNot Nothing Then If Microsoft.Win32.Registry.LocalMachine.OpenSubKey(regPfad).GetValue("CurrentVersion") IsNot Nothing Then jCurrVersion = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(regPfad).GetValue("CurrentVersion").ToString regPfad = "SOFTWARE\WOW6432Node\JavaSoft\Java Runtime Environment\" & jCurrVersion If Microsoft.Win32.Registry.LocalMachine.OpenSubKey(regPfad).GetValue("JavaHome") IsNot Nothing Then jHomeDir = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(regPfad).GetValue("JavaHome").ToString End If End If End If End If If jHomeDir = "" Then MessageBox.Show("Java.exe kann nicht gefunden werden!" & Environment.NewLine & _ "Bitte kontaktieren Sie unsere Hotline.", "JAVA Fehler") Return False End If
Obwohl in der Registry der Eintrag "Java Runtime Environment" (wie auf allen anderen Rechnern) existiert, liefert "Microsoft.Win32.Registry.LocalMachine.OpenSubKey(regPfad)" Nothing zurück. Hab schon die Rechte für "SOFTWARE" auf "Vollzugriff" geändert - erfolglos. Hab den Virenscanner ausgeschaltet - erfolglos. Wie kann ich dem Fehler auf die Schliche kommen? Weiss jemand Rat?
Danke für eine Antwort.
Grüße Norbert
Antworten
-
Hab den Fehler gefunden. In den Zeilen mit jHomeDir = hatte ich nicht rk, sondern wieder Registry.LocalMachine angezogen.
Will man also unabhängig von der Kompilierung (AnyCPU, x86, x64) und unabhängig von der Maschine (32 Bit, 64 Bit) auf einen bestimmten Registry-Key zugreifen, dann ist der folgende Code richtig:
Dim jHomeDir As String = "" Dim jCurrVersion As String = "" Dim rk As Microsoft.Win32.RegistryKey Dim regPfad As String = "SOFTWARE\JavaSoft\Java Runtime Environment" rk = Microsoft.Win32.RegistryKey.OpenBaseKey(Microsoft.Win32.RegistryHive.LocalMachine, Microsoft.Win32.RegistryView.Registry64) If rk.OpenSubKey(regPfad) IsNot Nothing Then If rk.OpenSubKey(regPfad).GetValue("CurrentVersion") IsNot Nothing Then jCurrVersion = rk.OpenSubKey(regPfad).GetValue("CurrentVersion").ToString regPfad = "SOFTWARE\JavaSoft\Java Runtime Environment\" & jCurrVersion If rk.OpenSubKey(regPfad).GetValue("JavaHome") IsNot Nothing Then jHomeDir = rk.OpenSubKey(regPfad).GetValue("JavaHome").ToString End If End If End If If jHomeDir = "" Then regPfad = "SOFTWARE\WOW6432Node\JavaSoft\Java Runtime Environment" rk = Microsoft.Win32.RegistryKey.OpenBaseKey(Microsoft.Win32.RegistryHive.LocalMachine, Microsoft.Win32.RegistryView.Registry32) If rk.OpenSubKey(regPfad) IsNot Nothing Then If rk.OpenSubKey(regPfad).GetValue("CurrentVersion") IsNot Nothing Then jCurrVersion = rk.OpenSubKey(regPfad).GetValue("CurrentVersion").ToString regPfad = "SOFTWARE\JavaSoft\Java Runtime Environment\" & jCurrVersion If rk.OpenSubKey(regPfad).GetValue("JavaHome") IsNot Nothing Then jHomeDir = rk.OpenSubKey(regPfad).GetValue("JavaHome").ToString End If End If End If End If
Danke nochmal an alle. Das Problem ist gelöst.
Viele Grüße Norbert
- Als Antwort markiert norbert3 Mittwoch, 7. Dezember 2016 12:28
Alle Antworten
-
Hab bei der Suche nach einer Lösung im Net gefunden, dass man über eine Instanz auf den RegKey zugreifen muss. Habs jetzt so geändert:
Dim rkLocalMachine As Microsoft.Win32.RegistryKey = Microsoft.Win32.Registry.LocalMachine If rkLocalMachine.OpenSubKey(regPfad) IsNot Nothing Then If rkLocalMachine.OpenSubKey(regPfad).GetValue("CurrentVersion") IsNot Nothing Then jCurrVersion = rkLocalMachine.OpenSubKey(regPfad).GetValue("CurrentVersion").ToString regPfad = "SOFTWARE\JavaSoft\Java Runtime Environment\" & jCurrVersion If rkLocalMachine.OpenSubKey(regPfad).GetValue("JavaHome") IsNot Nothing Then jHomeDir = rkLocalMachine.OpenSubKey(regPfad).GetValue("JavaHome").ToString End If End If rkLocalMachine.Close() End If
Aber es hat nichts gebracht.
-
Hallo Norbert,
hast du schon mal versucht das Problem zu reproduzieren? Ich habe deinen Code einfach mal auf einer Windows 10 Pro x64 VM mit installiertem Java ausprobiert. Zumindest dort hatte ich keine Probleme und bekam den richtigen Pfad zurück. Mit welchem Betriebssystem in welcher Architektur gibt es denn Probleme? Weiterhin wäre noch wichtig zu wissen wie du dein Programm kompilierst. Denn es macht einen unterschied ob es als x86 oder x64 Prozess läuft.
Übrigens: Anstatt die verschiedenen Keys auszufragen kannst du auch die verschiedenen Registry Views durchtesten. Das wäre für mein Verständnis sauberer. Auch wenn dabei nicht anderes heraus kommen sollte.
Zu deinem eigenen Post: Registry ist eine statische Klasse und LocalMachine eine Eigenschaft die einen RegistryKey zurück gibt. Ob du dir diesen Wert in einer zusätzlichen Variable speicherst oder jedes mal direkt auf LocalMachine zugreifst ist egal.
Tom Lambert - .NET (C#) MVP
Wozu Antworten markieren und für Beiträge abstimmen? Klicke hier.
Nützliche Links: .NET Quellcode | C# ↔ VB.NET Konverter | Account bestätigen (Verify Your Account)
Ich: Webseite | Code Beispiele | Facebook | Twitter | Snippets -
Danke Tom! Wie gesagt: es läuft auf allen Maschinen, ob WIN 7 oder WIN 10. Bei mir und bei allen Anwendern. Nur auf dem einen Rechner mit WIN 7 nicht. Ich kompiliere unter Any CPU (weil einige Peripheriegeräte sich sonst nicht steuern lassen). Auf einigen Rechnern hat sich Java direkt unter SOFTWARE eingetragen, auf anderen unter WOW3264. Das macht keine Unterschiede, denke ich, denn es funktioniert überall.
Ich werde jetzt mal eine App kompilieren, wo andere Keys angefasst werden, ob zu sehen, ob überhaupt ein Zugriff stattfindet und es nur bei "Java" Probleme gibt. Über Registry Views weiss ich nichts, müsste mich erst belesen.
-
Nun hab ich das gefunden:
When you do a GetSubKeyNames() on the "SOFTWARE" key you are redirected to SOFTWARE\Wow6432Node
In der Tat gibt es auf den Rechnern, die ich hier prüfen kann, den Java-Eintrag auch unter WOW6432. Scheinbar ist auf dem Problemrechner eine Java 64er Version installiert worden, und die hat sich nicht unter WOW6432 eingetragen. Der Aufruf zum Auslesen der Registry wird aber wahrscheinlich unter Any CPU-Kompilierung gleich umgeleitet zu WOW6432? Komme ich da zum Ziel, wenn ich Registry Views verwende? Wie müsste das in VB aussehen?
-
Am 04.12.2016 schrieb norbert3:
When you do a GetSubKeyNames() on the "SOFTWARE" key you are redirected to SOFTWARE\Wow6432Node
In der Tat gibt es auf den Rechnern, die ich hier prüfen kann, den Java-Eintrag auch unter WOW6432. Scheinbar ist auf dem Problemrechner eine Java 64er Version installiert worden, und die hat sich nicht unter WOW6432 eingetragen. DerIn WOW6432 trägt sich auf einem 64-Bit Client die 32-Bit Software ein.
Siehe auch hier: http://www.wintotal.de/tipparchiv/?id=1921
https://de.wikipedia.org/wiki/WOW64Servus
Winfried
WSUS Package Publisher: http://wsuspackagepublisher.codeplex.com/
HowTos zum WSUS Package Publisher http://www.wsus.de/wpp
GPO's: http://www.gruppenrichtlinien.de
NNTP-Bridge für MS-Foren: http://communitybridge.codeplex.com/ -
Hab jetzt Beispielcode zu Registry Views gefunden. Es sieht jetzt so aus:
Dim jHomeDir As String = "" Dim jCurrVersion As String = "" Dim rk As Microsoft.Win32.RegistryKey Dim regPfad As String = "SOFTWARE\JavaSoft\Java Runtime Environment" rk = Microsoft.Win32.RegistryKey.OpenBaseKey(Microsoft.Win32.RegistryHive.LocalMachine, Microsoft.Win32.RegistryView.Registry64) If rk.OpenSubKey(regPfad) IsNot Nothing Then If rk.OpenSubKey(regPfad).GetValue("CurrentVersion") IsNot Nothing Then jCurrVersion = rk.OpenSubKey(regPfad).GetValue("CurrentVersion").ToString regPfad = "SOFTWARE\JavaSoft\Java Runtime Environment\" & jCurrVersion If rk.OpenSubKey(regPfad).GetValue("JavaHome") IsNot Nothing Then jHomeDir = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(regPfad).GetValue("JavaHome").ToString End If End If End If If jHomeDir = "" Then regPfad = "SOFTWARE\WOW6432Node\JavaSoft\Java Runtime Environment" rk = Microsoft.Win32.RegistryKey.OpenBaseKey(Microsoft.Win32.RegistryHive.LocalMachine, Microsoft.Win32.RegistryView.Registry32) If rk.OpenSubKey(regPfad) IsNot Nothing Then If rk.OpenSubKey(regPfad).GetValue("CurrentVersion") IsNot Nothing Then jCurrVersion = rk.OpenSubKey(regPfad).GetValue("CurrentVersion").ToString regPfad = "SOFTWARE\JavaSoft\Java Runtime Environment\" & jCurrVersion If rk.OpenSubKey(regPfad).GetValue("JavaHome") IsNot Nothing Then jHomeDir = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(regPfad).GetValue("JavaHome").ToString End If End If End If End If
Das funktioniert gut, aber nur auf meinem Entwicklungsrechner. Wenn es auf dem bockigen Rechner (einen anderen hab ich noch nicht probiert) ausgeführt wird, kommt eine Exception (kein Objektverweis). Kennt er OpenBaseKey nicht? Ein Framework > 4 müsste eigentlich drauf sein, denn die gesamte App (und auch die betreffende DLL) ist unter Zielframework 4.5 kompiliert. Kann sich nochmal jemand erbarmen?
Viele Grüße Norbert
-
Hab den Fehler gefunden. In den Zeilen mit jHomeDir = hatte ich nicht rk, sondern wieder Registry.LocalMachine angezogen.
Will man also unabhängig von der Kompilierung (AnyCPU, x86, x64) und unabhängig von der Maschine (32 Bit, 64 Bit) auf einen bestimmten Registry-Key zugreifen, dann ist der folgende Code richtig:
Dim jHomeDir As String = "" Dim jCurrVersion As String = "" Dim rk As Microsoft.Win32.RegistryKey Dim regPfad As String = "SOFTWARE\JavaSoft\Java Runtime Environment" rk = Microsoft.Win32.RegistryKey.OpenBaseKey(Microsoft.Win32.RegistryHive.LocalMachine, Microsoft.Win32.RegistryView.Registry64) If rk.OpenSubKey(regPfad) IsNot Nothing Then If rk.OpenSubKey(regPfad).GetValue("CurrentVersion") IsNot Nothing Then jCurrVersion = rk.OpenSubKey(regPfad).GetValue("CurrentVersion").ToString regPfad = "SOFTWARE\JavaSoft\Java Runtime Environment\" & jCurrVersion If rk.OpenSubKey(regPfad).GetValue("JavaHome") IsNot Nothing Then jHomeDir = rk.OpenSubKey(regPfad).GetValue("JavaHome").ToString End If End If End If If jHomeDir = "" Then regPfad = "SOFTWARE\WOW6432Node\JavaSoft\Java Runtime Environment" rk = Microsoft.Win32.RegistryKey.OpenBaseKey(Microsoft.Win32.RegistryHive.LocalMachine, Microsoft.Win32.RegistryView.Registry32) If rk.OpenSubKey(regPfad) IsNot Nothing Then If rk.OpenSubKey(regPfad).GetValue("CurrentVersion") IsNot Nothing Then jCurrVersion = rk.OpenSubKey(regPfad).GetValue("CurrentVersion").ToString regPfad = "SOFTWARE\JavaSoft\Java Runtime Environment\" & jCurrVersion If rk.OpenSubKey(regPfad).GetValue("JavaHome") IsNot Nothing Then jHomeDir = rk.OpenSubKey(regPfad).GetValue("JavaHome").ToString End If End If End If End If
Danke nochmal an alle. Das Problem ist gelöst.
Viele Grüße Norbert
- Als Antwort markiert norbert3 Mittwoch, 7. Dezember 2016 12:28