Fehlermeldung/Verzeichnis-Überwachung

Statement zur DSGVO im Forum

Alles zur DSGVO und zur Umsetzung im Forum hier: Statement zur DSGVO (letztes Update: 30.05.2018)
  • Hallo zusammen


    ich bekomme bei einem Script, das ein Netzlaufwerk-Verzeichnis überwachen soll, dauernd eine Fehlermeldung, bei der ich nicht weiterkomme. Der betreffende Teil des Scripts ist aus einem Forum-Eintrag im englischen Forum, das für meine Kenntnisse leider zu schwierig ist.


    Die Fehlermeldung:

    $colMonitoredEvents = $objWMIService.ExecNotificationQuery ("SELECT * FROM __InstanceOperationEvent WITHIN 5 WHERE " & "Targetinstance ISA 'CIM_DirectoryContainsFile' and " & "TargetInstance.GroupComponent= " & "'Win32_Directory.Name=""\\\tsclient\C\RD Files""'") $colMonitoredEvents = $objWMIService^ ERROR


    Die Fehlermeldung an sich bedeute, dass der Wert der Variable $colMonitoredEvents nicht gesetzt werden konnte, soviel ich bisher erfahren konnte. Aber warum das so sein soll, ist mir schleierhaft. Hier das Script:

    Könnte mir bitte jemand sagen, was hier das Problem sein könnte? Das einzigste, was ich bei dieser Variable $colMonitoredEvents geändert habe, ist das zu überwachende Verzeichnis.


    Danke für jeden Tipp.

  • Hallo bigeasy76

    Wenn du auf Fehler nach ObjGet prüfen würdest, müsste dir auch einer angezeigt werden, weil die Zeile nicht stimmt. Da fehlen Backslashs. $objWMIService = ObjGet("winmgmts\\:" & $strComputer & "root\cimv2").

    Bei dem Verzeichnis handelt es sich um einen freigegebenen Ordner? In einem Bsp. mit einem Laufwerk habe ich gesehen, dass dort C:\\\\Ordner stand. So funktioniert es bei mir mutmaßlich auch mit einem freigegebenen Ordner (Freigabename\\\\Unterordner).


    Allerdings würde ich dir den Vorschlag machen, einfach die FileSystemMonitor UDF aus dem englischen Forum zu verwenden.


    OT: In Bezug auf den anderen Thread würde ich statt auf Änderungen in einer Textdatei zu prüfen, mit dem anderen Skript einfach eine Datei schreiben, welche die Telefonnummer als Bezeichnung trägt. Dann sparst du dir auch das auslesen.

  • Ahoi autoiter


    Danke für die Hilfe, jedoch kommt bei mir derselbe Fehler immernoch, auch wenn ich Deine Korrektur drin habe. Verzeichnis ist freigegeben und auch mit Explorer auf dem RD erreichbar. Woran könnte es wohl noch liegen?


    Das mit dem FileSystemMonitor muss ich zuerst noch genauer studieren, kapier das noch nicht ganz richtig, wie ich das in meinem Beispiel anwenden müsste und mir fiel auf, dass in meinem Include-Ordner FileSystemMonitor.au3 nicht enthalten ist, obwohl V3.3 installiert. Diese Datei müsste doch da sein, nicht?

  • Hey bigeasy76

    jedoch kommt bei mir derselbe Fehler immernoch, auch wenn ich Deine Korrektur drin habe. Verzeichnis ist freigegeben und auch mit Explorer auf dem RD erreichbar

    Wie sieht denn deine Ordnerangabe nun aus? Und nur zur Sicherheit: Das Verzeichnis ist mit dem Explorer "auf dem RD erreichbar". Was meinst du? Eigentlich sollte das jetzt nichts mit Remote Desktop zu tun haben. Du hast die Freigabe doch auf dem Rechner auf dem du arbeitest eingebunden, oder?


    Die meisten UDF sind nicht in der Standard-Installation von AutoIt. Du hast verschiedene Möglichkeiten diese einzubinden. Das einfachste für heute ist, die UDF in das Skriptverzeichnis zu legen. Wenn du bei der include-Anweisung statt <> Gänsefüßchen angibst (""), wird zuerst in diesem Verzeichnis nach dem eingebundenen Skript gesucht. Also einfach herunterladen, ins Skriptverzeichnis ablegen, include-Anweisung angeben und du kannst die Befehle nutzen.

    Das ist der Link der UDF. Hier der Link zum Explorer Bsp.

    Lege beide Skripte im gleichen Verzeichnis ab und starte das Beispiel. Da sollte sich schon vieles erklären ;) Die anderen Beispiele kannst du genauso testen.

  • Allerdings würde ich dir den Vorschlag machen, einfach die FileSystemMonitor UDF aus dem englischen Forum zu verwenden.

    Das Teil hatte ich auch mal getestet... es ist aber gar nicht nötig, denn die WinAPI hat dafür doch alles, was man braucht...

    _WinAPI_RegisterWindowMessage, _WinAPI_ShellChangeNotifyRegister, _WinAPI_ShellGetPathFromIDList, _WinAPI_ShellChangeNotifyDeregister


    Der oder die zu überwachenden Pfade können entweder als String, oder als Array übergeben werden. In der AutoIt-Hilfe gibt es auch ein Beispiel dafür.

  • Guten Morgen die Herren


    autoiter : Die Ordnerübergabe sieht nun so aus:

    "'Win32_Directory.Name=""M:\RD Files""'"


    Bitnugger : Danke für den Tipp, hab mir das angesehen, habs nun mal mit folgendem aus der englischen Autoit-Hilfe probiert:

    Hier ist nun aber das Problem, dass kein Event angezeigt wird, wenn das andere Script die txt-Datei mit der Nummer befüllt, es wird nur jede Sekunde die Meldung Event: 0x00001000 | Path: M:\angezeigt. Leider sind meine Kenntnisse hier auch zu klein, um zu verstehen, wieso das so ist. Meine Vermutung war, dass bei

    Code
    1. Global $g_iID = _WinAPI_ShellChangeNotifyRegister($hWnd, $iMsg, $SHCNE_ALLEVENTS, BitOR($SHCNRF_INTERRUPTLEVEL, $SHCNRF_SHELLLEVEL, $SHCNRF_RECURSIVEINTERRUPT), $g_sPath, 1)

    auch noch der Parameter $SHCNRF_NEWDELIVER rein müsste, das hat aber nicht wirklich geklappt. Kann mir einer der Profis bitte einen Tipp geben?

  • Hallo bigeasy76

    "'Win32_Directory.Name=""M:\RD Files""'"

    In Beitrag 2 hatte ich es doch so vorgeschlagen: M:\\\\RD Files. Hatte das nicht geklappt.


    Aber egal. Bitnuggers Vorschlag war gut. Nimm einfach das.

    Ich habe das Beispiel aus der Hilfe nur so umgebogen, dass im Skriptverzeichnis der Ordner TEST erstellt und da hineingeschrieben wird. Da wird dann alle zwei Sekunden eine Datei mit einer Telefonnummer als Bezeichnung erstellt. Die Dateien werden in der SciTE-Konsole angezeigt. Wenn du in der While-Schleife die FileWrite-Zeile auskommentierst und die anderen drei (FileOpen usw.) laufen lässt, wird stattdessen in die Datei geschrieben. Das siehst du auch in der Konsole. Du musst dann aber die Datei auslesen.


  • In Beitrag 2 hatte ich es doch so vorgeschlagen: M:\\\\RD Files. Hatte das nicht geklappt.

    Hallo autoiter , sorry, das vergass ich zu erwähnen, habs dort auch mit 4, 3 und 2 Backslashes versucht, das ergab leider immer denselben Fehler


    Edit: Dein angepasstes Beispiel habe ich versucht, anzuwenden, aber das erstellt nur diese Dateien mit Zufallszahlen, ich versteh hier leider nicht, wie mir das beim Auslesen der Datei telefon.txt hilft, wenn diese Datei geändert wurde.

  • Das sollte dir nur vor Augen führen, dass die Events registriert werden.

    Ich hielt es dabei für einfacher für dich, wenn immer eine neue Datei direkt mit der Nummer als Bezeichnung erstellt wird. Im Gunde spielt es aber keine Rolle. Wenn es dir aus irgendeinem Grund lieber ist, in eine Datei zu schreiben und die dann auszulesen, dann funktioniert das auch.

    Lösche einfach alles innerhalb der While-Schleife, öffne die Datei, schreibe etwas hinein und speichere. Du siehst in SciTE-Konsole das Event.


    EDIT bigeasy76  

    Nur noch mal zur Sicherheit. Die Ausgabe in der SciTE-Konsole siehst du aufgrund der Zeile ConsoleWrite('Event: 0x' & Hex($lParam) & ' | Path: ' & $sPath & @CRLF) in der Funktion WM_SHELLCHANGENOTIFY. Hier musst du eigentlich nur deine Reaktion einbauen..

  • Vielen Dank, autoiter , habs nun langsam kapiert. Das mit dem Erstellen einer Datei mit der Nummer als Bezeichnung hab ich mir überlegt, das käme ja dann ins andere Script. Aber dort hab ich die Telefonnummer schon so formatiert (000/0000000), wie sie in die Eingabemaske reinmuss und Slashes sind vermutlich auch hier verboten in Dateinamen.


    Nochmals zum Script von Deinem Beitrag #7, hab da die Zeilen 19-26 versucht, in eine While-Schleife zu packen, damit das Verzeichnis dauernd überwacht wird. Bei mir beendet sich das Script sonst von selbst nach ca 2s. Aber mit dieser While-Schleife wir die Funktion etliche male aufgerufen, wenn das txt geändert wird. Wie krieg ich das hin, dass es nur einmal durchläuft? Das krieg ich irgendwie nicht hin, ohne dass die Überwachung des Verzeichnisses auch gestoppt wird.

    Ansonsten läuft nun alles tiptop, vielen Dank für die wiederum tolle Hilfe und Geduld mit einem Anfänger!

    Edit:

    Habs nun doch so zum Laufen gebracht, dass alles funktioniert mit dieser Schleife. In der Funktion, die die Nr in die Eingabemaske eingefügt hat, wurde die Nr. anschliessend wieder gelöscht im txt, vermutlich wurde durch diese Änderung alles in eine Endlosschleife versetzt.


    Aber nochmals vielen Dank für die Hilfe!!!

  • Nein, das muss wieder aus der While-Schleife raus.

    Die Frage ist, warum wird das Skript beendet?

    Gibt es im Konsolenbereich von SciTE eine Fehlermeldung?


    Aber dort hab ich die Telefonnummer schon so formatiert (000/0000000), wie sie in die Eingabemaske reinmuss und Slashes sind vermutlich auch hier verboten in Dateinamen.

    Das ist eigentlich gar kein Problem. Du kannst einfach etwa einen Bindestrich nehmen, der dann im Skript mit StringReplace ersetzt wird. Schau dir mal diese Variante an. Hier wird wieder in der While-Schleife alle 2 Sekunden eine Datei mit einem Bindestrich geschrieben, der dann in der Ausgabe (Inhalt der Variable $sNumber) mit Schrägstrich erscheint.

    Bricht dieses Skript auch einfach bei dir ab? Wie sieht die Ausgabe der SciTE-Konsole aus?

  • Fehlermeldung gabs keine. Habs nun so und das funktioniert:

  • Wie du magst. Ich frage mich nur, was mit den ganzen _WinAPI_RegisterWindowMessage('SHELLCHANGENOTIFY') passiert, die du nie wieder aufhebst.. :/ Aber da gibt es wissendere User als mich. Ich würde dir aber raten, die Effekte im Dauerbetrieb erst einmal genau zu beobachten.

  • Reicht das nicht, wenn mit Beendung des Scripts mit der Func OnAutoItExit() die _WinAPI_RegisterWindowMessage('SHELLCHANGENOTIFY') wieder aufgehoben wird? so wars ja auch ursprünglich im Beispiel.


    Edit: Wenn ichs ohne diese Schleife laufen lasse, erhalte ich folgende Ausgabe, das Script beendet dann:

    >Exit code: 0 Time: 2.65

  • Aufgehoben wird am Ende das Handle (oder Identifier), das zuletzt in $g_iID gespeichert war. Du überschreibst den Inhalt dieser Variable aber alle 0,2 Sekunden. Da kommt auf Dauer eine stattliche Anzahl an registrierten Fenstern zustande, die (soweit ich sehe) nicht aufgehoben werden. Denn du deregistrierst ja nur das letzte.

  • Würde es was bringen, wenn ich in der Schleife mit GuiDelete() das Fenster wieder beenden würde? Oder was könnte dann das Problem sein, dass das Script beendet, wenn ich die While-Schleife weglasse, Du meinst ja, es müsste dann trotzdem funktionieren ohne von selbst zu beenden?

  • Nein. Du müsstest schon _WinAPI_ShellChangeNotifyDeregister verwenden, wie in der Funktion, die beim Beenden des Skripts aufgerufen wird.
    Aber ehrlich gesagt, halte ich das nicht für glücklich.


    Wenn das Skript, dass aus Post 11 ohne Änderungen durch dich nach kurzer Zeit abbricht, bin ich einfach auch überfordert. Keine Ahnung ob das ein XP Ding ist. Ich denke du brauchst hier einen Fähigeren, der dir hilft.


    Edit:

    bigeasy76 Wenn du bei dieser Variante bleibst, dann würde ich dir wenigstens empfehlen, die Variablen nicht in der Schleife zu deklarieren, sondern davor/darüber (die Variablen dort sind eigentlich alle Global). So überschreibst du die Variable statt immer eine neue zu erstellen.

  • $SHCNRF_NEWDELIVERY

    Diese Konstante ist in APIShellExConstants.au3 nicht deklariert, da hast du dich verschrieben... richtig wäre: $SHCNRF_NEWDELIVERY (Messages received use shared memory.)

    Es wird sogar von Microsoft empfohlen, dieses Flag zu benutzen... alle Clients sollten dies tun... im lokalen Netzwerk spielt es aber wohl kaum eine Rolle und mehr als $SHCNE_ALLEVENTS geht ja wohl nicht.

    Mit Opt('MustDeclareVars', 1) wäre dir das nicht passiert. 8o


    Diese kleine Demo hier sollte auch bei dir funktionieren...

  • Denn du deregistrierst ja nur das letzte.

    So wie ich das verstehe, passiert in der While-Schleife in Zeile 26 im Prinzip gar nichts, außer das Zeit vergeudet wird... weil sich die Parameter nicht geändert haben...


    Im vorigen Post im Script..

    ;~ ********************************************************************************************************************************************************

    ;~ Das Beispiel in der AutoIt-Hilfe zu _WinAPI_ShellChangeNotifyRegister funktioniert nicht auf 64-Bit-Systemen, weil die erstellte Struktur für 32-Bit ausgelegt ist!!!

    ;

    ;~ FALSCH --> Local ... $sPath = _WinAPI_ShellGetPathFromIDList(DllStructGetData(DllStructCreate('dword Item1; dword Item2', $wParam), 'Item1'))

    ;

    ;~ So funktioniert es auf 32/64-Bit-Systemen!!!

    ;

    Local $sMsg, $sNewItems, $sEventNowCalc = _NowCalc(), $sEventNow = _Now(), _

    $sPath = _WinAPI_ShellGetPathFromIDList(DllStructGetData(DllStructCreate('INT_PTR Item1; INT_PTR Item2', $wParam), 'Item1'))

    ;~ ********************************************************************************************************************************************************




    Deshalb stürzte das Script nach kurzer Zeit ab...

  • Hallo autoiter & Bitnugger


    vielen Dank erstmal für die Geduld mit mir! Das Beispiel von Bitnugger habe ich mit wenigen Anpassungen zu Laufen gebracht, wenn ein Anruf eingeht, wird die Nummer nun in die Eingabemaske auf dem RD eingegeben und der Datensatz des Kunden - wenn vorhanden - wird mir gleich angezeigt. Das erleichtert meine Arbeit enorm, daher nochmals vielen Dank an die Herren für die Hilfe! Und nun kann ich bei Gelegenheit auch den Vorschlag von autoiter umsetzen, dass die Filebezeichnung=Nummer entspricht.


    Wünsche allerseits einen angenehmen Sonntag!