Registry: Key/Value überwachen (WMI) - Error: Nicht analysierbare Abfrage.

  • VB.NET

Es gibt 20 Antworten in diesem Thema. Der letzte Beitrag () ist von BitBrösel.

    Registry: Key/Value überwachen (WMI) - Error: Nicht analysierbare Abfrage.

    Ich möchte einen Registry-Key bzw. Key.Value überwachen.

    Meines Erachtens ist der Code richtig, funktioniert bei mir aber nicht wie gewünscht, ich befürchte mein System ist etwas angeschlagen.
    Also bitte ich darum, die TestSolution (Anhang) auszuprobieren und mir feedback zukommen zu lassen.

    VB.NET-Quellcode

    1. Imports System.Management
    2. Public Class RegistryWatcher
    3. Public Watcher As ManagementEventWatcher
    4. Sub New()
    5. End Sub
    6. Public Sub New(ByVal hive As String, ByVal keyPath As String, ByVal Optional valueName As String = "")
    7. Try
    8. Dim query As New WqlEventQuery(
    9. $"SELECT * FROM RegistryValueChangeEvent WHERE Hive = '{hive}' AND KeyPath = '{keyPath}'" &
    10. If(valueName <> "", $"AND ValueName='{valueName}'", valueName))
    11. Watcher = New ManagementEventWatcher(query)
    12. AddHandler Watcher.EventArrived, AddressOf Watcher_EventArrived
    13. AddHandler Watcher.Stopped, AddressOf Watcher_Stopped
    14. Catch managementException As ManagementException
    15. Console.WriteLine($"Error: {managementException.Message}")
    16. End Try
    17. End Sub
    18. Public Sub Start()
    19. Try
    20. Watcher.Start()
    21. Console.WriteLine("Waiting for an event...")
    22. Catch managementException As ManagementException
    23. Console.WriteLine($"Error: {managementException.Message}")
    24. End Try
    25. End Sub
    26. Public Sub [Stop]()
    27. Watcher.Stop()
    28. End Sub
    29. Private Sub Watcher_EventArrived(sender As Object, e As EventArrivedEventArgs)
    30. Console.WriteLine("Received an event.")
    31. End Sub
    32. Private Sub Watcher_Stopped(sender As Object, e As EventArgs)
    33. Console.WriteLine("Stopped.")
    34. End Sub
    35. End Class


    Console schrieb:

    Ausnahme ausgelöst: "System.Management.ManagementException" in System.Management.dll
    Error: Nicht analysierbare Abfrage.


    Interessanterweise wird noch vor der Fehlermeldung das Stoped Event gefeuert. :huh:
    Dateien

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „FormFollowsFunction“ ()

    Ups ! Ne daran liegt es nicht, die Fehlermeldung hatte ich schon bevor ich den Teil eingebaut habe.
    Aber Danke für den Hinweis !

    Korregierte Version jetzt im Start-post verfügbar.
    Ich hab was bei stackoverflow gefunden: Beim Registry-Pfad muss man in Deinem Programm statt einfachen \ doppelte nehmen => SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    Jawoll, das wars ! :thumbsup:
    Warum ist mir das nur entgangen ? 'Slap myself'

    Lauffähige Version:

    VB.NET-Quellcode

    1. Imports System.Management
    2. Public Class RegistryWatcher
    3. Public Watcher As ManagementEventWatcher
    4. Sub New()
    5. End Sub
    6. Public Sub New(ByVal hive As String, ByVal keyPath As String, ByVal Optional valueName As String = "")
    7. Try
    8. Dim query As New WqlEventQuery(
    9. $"Select * FROM " &
    10. If(valueName = "", "RegistryKeyChangeEvent", "RegistryValueChangeEvent") &
    11. $" WHERE Hive = '{hive}' AND KeyPath = '{keyPath.Replace("\", "\\")}'" &
    12. If(valueName = "", valueName, $" AND ValueName='{valueName}'"))
    13. Watcher = New ManagementEventWatcher(query)
    14. AddHandler Watcher.EventArrived, AddressOf Watcher_EventArrived
    15. AddHandler Watcher.Stopped, AddressOf Watcher_Stopped
    16. Catch managementException As ManagementException
    17. Console.WriteLine($"Error: {managementException.Message}")
    18. End Try
    19. End Sub
    20. Public Sub Start()
    21. Try
    22. Watcher.Start()
    23. Console.WriteLine("Waiting for an event...")
    24. Catch managementException As ManagementException
    25. Console.WriteLine($"Error: {managementException.Message}")
    26. End Try
    27. End Sub
    28. Public Sub [Stop]()
    29. Watcher.Stop()
    30. End Sub
    31. Private Sub Watcher_EventArrived(sender As Object, e As EventArrivedEventArgs)
    32. Console.WriteLine("Received an event.")
    33. End Sub
    34. Private Sub Watcher_Stopped(sender As Object, e As EventArgs)
    35. Console.WriteLine("Stopped.")
    36. End Sub
    37. End Class
    Moin!

    ich würde gerne die o.g. Funktion nutzen - nur leider stehe ich bei diesen Watchern irgendwie auf dem Schlauch.

    Mit Start wird die Sache aktiviert - aber wie rufe ich eine Funktion auf, wenn ein event ausgelöst wird?

    Kann mir einer weiterhelfen?

    Gurß Jan

    jan99 schrieb:

    wie rufe ich eine Funktion auf, wenn ein event ausgelöst wird?
    Mit dem Auslösen des Events wirst Du doch informiert, dass das überwachte Szenario ausgelöst wird.
    In Post #5 sind es die EventHandler Watcher_EventArrived und Watcher_Stopped.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Moin!

    Danke zunächst einmal - aber da fängt meine Baustelle genau an.

    Ich werde mich einmal daran versuchen.

    Als Basis habe ich mir eigene Events aus einem Objekt auslösen und einen Handler in einer Form aufrufen herangezogen.

    Soweit bin ich mit meinen Gedanken gekommen.... Leider komme ich aber bei der Definition von SetCurrentGrundstück_AutoCall() nicht weiter.

    VB.NET-Quellcode

    1. Imports System
    2. Imports System.IO
    3. Imports System.Windows.Forms
    4. Imports Microsoft.Office.Tools.Ribbon
    5. Imports Word = Microsoft.Office.Interop.Word
    6. Imports System.Diagnostics
    7. Imports Microsoft.Office.Interop.Word
    8. Public Class Ribbon
    9. Private _objWord As Word.Application
    10. Private _objDoc As Word.Document
    11. Private _Template As EBL.WinWord.OpenTemplate
    12. Private _Tools As New EBL.WinWord.Tools
    13. Private _Para As New EBL.WinWord.Parameter
    14. Private WithEvents _fRegWatcher As New EBL.Service.NonAcad.RegistryWatcher("HKEY_CURRENT_USER", "\SOFTWARE\EBL-CADGIS\CURRENT_GRDSTK", "test")
    15. Private Sub Ribbon_Load(ByVal sender As System.Object, ByVal e As RibbonUIEventArgs) Handles MyBase.Load
    16. _fRegWatcher.Start()
    17. SetCurrentGrundstück()
    18. End Sub
    19. Private Sub SetCurrentGrundstück_AutoCall() Handles _fRegWatcher.
    20. SetCurrentGrundstück()
    21. End Sub


    Kann mir jemand weiterhelfen?

    ... auch, ob die Intialisierung schon richtig ist.

    Gruß Jan

    jan99 schrieb:

    EBL.Service.NonAcad.RegistryWatcher
    Was ist das für eine Ding?
    Gibt es dafür eine DLL?
    Wenn ja: Kannst Du die mal anhängen und die zugehörige XML, so vorhanden?
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Das ist das Teil aus Post#1/#5. Nur eben in eigenem Namespace.
    @jan99: Das funktioniert nicht. Der selbstgebastelte RegistryWatcher feuert keine Events, weshalb Dir bei Handles _fRegWatcher. nix angezeigt wird. Das Teil ist "nur" ein Wrapper für den ManagementEventWatcher. Der feuert Events. Aber die werden vom RegistryWatcher konsumiert. Wenn Du willst, dass der RegistryWatcher was an Dein Programm per Event weiterleitet, musst Du in dieser Zeile selber mit RaiseEvent ein eigenes Ereignis abfeuern.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    Moin!

    *unnötiges Vollzitat entfernt*

    Die markierte Zeile bedeutet, dass ich dort meine zugehörige Funktion aufrufen muss?

    Jan

    ps: Wenn ich den RegistryWatcher in einer Klasse habe, dann muss ich dem ja nach meiner Vermutung die aufzurufende Funktion übergeben. Meine Frage an dieser Stelle. Kann ich eine Funktion eigentlich auch als Parameter an eine Klasse übergeben um diese dann dort einzubauen??

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „Marcus Gräfe“ ()

    kurz: ja.
    lang:
    Beispielcode

    VB.NET-Quellcode

    1. Public Class Form1
    2. Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    3. Dim Foo As New Foo
    4. Foo.MethodeMitSubAlsParameter(AddressOf ZeigeEinenText) 'der Methode wird die Adresse einer Sub mitgegeben
    5. Foo.MethodeMitSubAlsParameter(Sub() MessageBox.Show("Ich bin Teil einer anonymen Methode.")) 'der Methode wird eine sog. anonyme Sub direkt mitgegeben
    6. Foo.MethodeMitFunctionAlsParameter(AddressOf BinIchSichtbar) 'der Methode wird die Adresse einer Function mitgegeben
    7. Foo.MethodeMitFunctionAlsParameter(Function() Me.Enabled) 'der Methode wird eine sog. anonyme Function direkt mitgegeben
    8. End Sub
    9. Private Sub ZeigeEinenText()
    10. MessageBox.Show("Ich bin Teil einer Form1-Klassenmethode.")
    11. End Sub
    12. Private Function BinIchSichtbar() As Boolean
    13. Return Me.Visible
    14. End Function
    15. End Class
    16. Friend Class Foo
    17. Friend Sub MethodeMitSubAlsParameter(Action As Action)
    18. Action() 'die übergebende Sub wird aufgerufen
    19. End Sub
    20. Friend Sub MethodeMitFunctionAlsParameter(Func As Func(Of Boolean))
    21. Dim RückgabewertDerÜbergebendenFunction = Func.Invoke 'die übergebende Function wird aufgerufen …
    22. MessageBox.Show(RückgabewertDerÜbergebendenFunction.ToString) '…und das Ergebnis angezeigt
    23. End Sub
    24. End Class

    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    Moin!

    ich habe das Thema einmal wieder rausgekramt.

    Irgendwie komme ich ich mit dem Verständnis nicht weiter. Habe mir zu dem Stichwort "RaiseEvent" folgendes rausgesucht: RaiseEvent Tutorial

    Meine Klasse für den Registrywatcher ist ja aus Registry: Key/Value überwachen (WMI) - Error: Nicht analysierbare Abfrage. bekannt und mein Code der Einbindung aus Registry: Key/Value überwachen (WMI) - Error: Nicht analysierbare Abfrage. bekannt.

    Aber wo und wie ich da ein "RaiseEvent" einbauen soll damit es hier

    VB.NET-Quellcode

    1. Private Sub SetCurrentGrundstück_AutoCall() Handles _fRegWatcher.xxxx
    ein entsprechendes Event bereit stellt?

    Sorry, aber irgendwie verstehe ich das überhaupt nicht.

    Ich bin einfach nur am Verzweifeln.

    Jan
    Moin!

    es ist schon wieder ein halbes Jahr vergangen seit dem letzten Posting und ich bin die Sache nochmal angegangen. Jetzt habe ich einmal ein Testprojekt angegangen nach meinen "Vorstellungen" und vielleicht ist es irgendwie so zu ergänzen, dass es das mach was ich mir vorstelle und ich es auch verstehe.

    Zum Code:
    Hier gibt es eine Classe mit dem Watcher-Code und dann eine Form die nach dem Starten derzeit einfach nur leer ist.

    Dann werden beim Initalisieren zwei RegistryWatcher für folgende Keys angelegt:

    VB.NET-Quellcode

    1. Private WithEvents _fRegWatcher_1 As New RegistryWatcher("HKEY_CURRENT_USER", "\SOFTWARE\EBL-CADGIS\CURRENT_GRDSTK", "test1")
    2. Private WithEvents _fRegWatcher_2 As New RegistryWatcher("HKEY_CURRENT_USER", "\SOFTWARE\EBL-CADGIS\CURRENT_GRDSTK", "test2")


    Wenn diese sich im Wert ändern, dann möchte ich das eine Meldung kommt.

    Dafür habe ich zwei Funktionen angelegt, die allerdings noch etwas unvollständig sind.


    VB.NET-Quellcode

    1. Public Sub EventAt_1() Handles _fRegWatcher_1
    2. MsgBox("Es hat sich etwas bei TEST 1 geändert!")
    3. End Sub
    4. Public Sub EventAt_2() Handles _fRegWatcher_2
    5. MsgBox("Es hat sich etwas bei TEST 2 geändert!")
    6. End Sub


    Es fehlt da irgendwie hinter dem _fRegWatcher_1 noch der auslösender Händler.

    Nach meinem Verständnis müsste so oder ähnlich aussehen:

    VB.NET-Quellcode

    1. _fRegWatcher_1.Watcher_EventArrived


    Aber Watcher_EventArrived wird im Kontext nicht angeboten. <X

    Es kann doch nicht sein, dass für jede Registry-Überwachung immer eine ganze Klasse wie RegWatcher.vb angelegt werden muss!?!?!??!

    Gruß Jan
    Dateien
    Fang noch mal neu an mit den Events, schau in einem Buch nach oder nutze eine Quelle deiner Wahl was Event sind, wie man sie deklariert und feuert.

    In deiner Klasse RegistryWatcher sind keine Events zu finden die du von außen abonnieren kannst. Du hast in der Klasse zwar Events vom ManagementEventWatcher aboniert, die werden bestimmt ausgelöst, aber die sind ja von außen so wie du das hast nicht verfügbar.

    Also entweder alles nötige public machen, was die schlechte Lösung ist, oder eigene Events in der Klasse RegistryWatcher deklarieren, ich täte eigene EventArgs verwenden und alle nötigen Informationen da drin verfügbar machen. Dann löst du deine eigenen Events aus, wenn vom ManagementEventWatcher eines ausgelöst wurde.

    Kleiner Stups:

    Public Event MeinSuperEvent As EventHandler(Of MySuperArguments)

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „BitBrösel“ ()

    Moin!

    also, auch wenn das unschön ist, habe ich es erst einmal über Public versucht.

    Bekomme dann aber die Meldung, dass

    Das Ereignis "Watcher_EventArrived" wurde nicht gefunden. Test_RegWatcher C:\VSProjects\Konsolenanwendungen\Test_RegWatcher\Test_RegWatcher\Form1.vb 10 Aktiv


    Wenn ich aber meine Funktionen

    VB.NET-Quellcode

    1. Public Sub EventAt_1() Handles _fRegWatcher_1.Watcher_EventArrived
    2. MsgBox("Es hat sich etwas bei TEST 1 geändert!")
    3. End Sub
    4. Public Sub EventAt_2() Handles _fRegWatcher_2.Watcher_EventArrived
    5. MsgBox("Es hat sich etwas bei TEST 2 geändert!")
    6. End Sub


    auskommentiere kann ich ja das Programm dennoch starten. Was mich dann aber verwundert, dass zweimal hinter einander "Stopped" gemeldet wird. Irgendetwas muss den Watcher ja gleich anhalten.

    Etwas anderes in diesem Zusammenhang. Was bedeuten die eckigen Klammern bei

    VB.NET-Quellcode

    1. Public Sub [Stop]()
    2. Watcher.Stop()
    3. End Sub


    Oder ist das nur schmückendes Beiwerk?

    Gruß Jan

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „jan99“ ()

    Man darf keine Keywords für Namen nutzen, könnte der Compiler nicht interpretieren. Egal ob es Namen von Variablen, Funktionen, Subs oder whatever sind.
    Dafür sind dann die eckigen klammern, dann weiß der Compiler, hier nicht als Keyword gemeint.

    So sind dann auch solche Konstrukte denkbar.

    VB.NET-Quellcode

    1. Private Sub [Private]()
    2. End Sub
    3. Private Sub [Public]()
    4. End Sub


    Die Subs einfach Public zu machen ist falsch. Was hast du denn nun genau gemacht, diesen Code kannst du doch einfach mal posten, so viel ist das ja nicht. Der ManagementEventWatcher(oh ich sehe in der Mappe den hattest du ja Public, hatte irgendwie im Kopf das der nur im Kontruktor war). Also die Event Subs kannst du in der Klasse Private lassen, die sind von außen hier nicht relevant. Wenn du die Events vom ManagementEventWatcher von außen abonnierst kannste dir gleich die Klasse sparen. Wenn sofort Stop gefeuert wird, wird das wohl nicht an den Abos liegen. Schaur dir genau an, was in dem "Query" für den drin steht, evtl. ist da der Fehler.


    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „BitBrösel“ ()

    Moin!

    mein Code as is hänge ich jetzt einmal an.

    Gruß Jan

    Dateianhang bereinigt. Bitte ausführbare Dateien (insb. die Verzeichnisse bin und obj) beim Hochladen außerhalb des Showrooms entfernen. ~Thunderbolt
    Dateien

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Thunderbolt“ ()