none
OpenSubKey RRS feed

  • 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

    Sonntag, 4. Dezember 2016 09:57

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

    Sonntag, 4. Dezember 2016 11:06
  • 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

    Sonntag, 4. Dezember 2016 11:44
    Moderator
  • 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.

    Sonntag, 4. Dezember 2016 13:58
  • Andere Keys lassen sich auslesen (z.B. HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\DirectX --> Version)

    Meine nächste Idee: ich installiere Java jre (wie auf den anderen Rechnern, hab auf diesem jdk). Vielleicht liegt es daran?

    Sonntag, 4. Dezember 2016 14:21
  • Nee, hab mich geirrt: auch auf diesem Rechner ist jre.

    Jetzt nehm ich mir den Strick und erschiess mich ...

    Sonntag, 4. Dezember 2016 14:25
  • 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?

    Sonntag, 4. Dezember 2016 15:40
  • 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. Der

    In 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/WOW64

    Servus
    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/

    Sonntag, 4. Dezember 2016 17:05
  • 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

    Montag, 5. Dezember 2016 16:43
  • 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
    Mittwoch, 7. Dezember 2016 12:28