So erhalten Sie ein Ereignis zum Schließen einer Datei in Python

7

Verwenden von Python 2.7 auf Windows 7 64-Bit-Maschine.

So erhalten Sie ein Ereignis zum Schließen einer Datei:

  1. wenn die Datei in einem neuen Dateiöffnerprozess geöffnet wird (wie Notepad, Wordpad, der die Datei jedes Mal im neuen Prozess von Wordpad öffnet)
  2. wenn die Datei in einer Dateiöffnerdatei geöffnet wird (wie Notepad ++, die alle Dateien in der neuen Registerkarte öffnet, aber es gibt nur einen einzigen Prozess, der notepad ++ ausführt)

Also, wie in den oben genannten Fällen Datei schließen Ereignis zu bekommen? Ist es möglich, die oben genannten Fälle durch einen gemeinsamen Code zu erreichen? Ich habe es mit verschiedenen Dateitypen zu tun.

    
imp 14.03.2014, 13:25
quelle

4 Antworten

14

Dies hat sich als eine sehr einfache Aufgabe für * nix-Systeme erwiesen, aber unter Windows ist das Abrufen eines Ereignisses zum Schließen einer Datei keine einfache Aufgabe. Lesen Sie unten die Zusammenfassung der gebräuchlichen Methoden, die nach Betriebssystemen gruppiert sind.

Für Linux

Unter Linux können die Dateisystemänderungen leicht und sehr detailliert überwacht werden. Das beste Werkzeug hierfür ist das Kernel-Feature inotify , und es gibt eine Python-Implementierung namens Pynotify.

  • Pynotify

    Pyinotify ist ein Python-Modul zum Überwachen von Dateisystemänderungen. Pyinotify basiert auf einer Linux-Kernel-Funktion (im Kernel 2.6.13 zusammengeführt) namens inotify , die ein ereignisgesteuerter Notifier ist. Seine Benachrichtigungen werden über drei Systemaufrufe vom Kernel-Space in den Benutzerbereich exportiert. Pyinotify bindet diese Systemaufrufe und bietet darüber hinaus eine Implementierung, die eine generische und abstrakte Möglichkeit bietet, diese Funktionalitäten zu manipulieren.

    Hier finden Sie die Liste der Ereignisse, die mit Pynotify überwacht werden können.

    Beispielverwendung:

    pyinotify importieren

    %Vor%

Für Windows

Situation für Windows ist ein bisschen komplexer als für Linux. Die meisten Bibliotheken verlassen sich auf die ReadDirectoryChanges API, die eingeschränkt ist und keine feineren Details wie das Close-Ereignis der Datei erkennen kann. Es gibt jedoch andere Methoden zum Erkennen solcher Ereignisse. Lesen Sie weiter, um mehr zu erfahren.

  • Beobachter

    Hinweis: Watcher wurde zuletzt im Februar 2011 aktualisiert, daher ist es wahrscheinlich sicher, diesen zu überspringen.

    Watcher ist eine Low-Level-Erweiterung C für den Empfang von Dateisystemupdates mit der ReadDirectoryChangesW API auf Windows-Systemen. Das Paket enthält auch eine High-Level-Schnittstelle, um die meisten .NET FileSystemWatcher API zu emulieren.
    Die Erkennung von Ereignissen zum Schließen von Dateien mit Watcher kann am nächsten sein, um die Ereignisse FILE_NOTIFY_CHANGE_LAST_WRITE und / oder FILE_NOTIFY_CHANGE_LAST_ACCESS zu überwachen.

    Beispielverwendung:

    %Vor%
  • Wachhund

    Python-API und Shell-Dienstprogramme zur Überwachung von Dateisystemereignissen. Einfache Installation: $ pip install watchdog . Weitere Informationen finden Sie in der Dokumentation .
    Der Watchdog unter Windows beruht auf der ReadDirectoryChangesW API, was seine Vorbehalte gegenüber Watcher und anderen Bibliotheken, die auf derselben API basieren, mit sich bringt.

  • Pywatch

    Ein Python-Near-Clone des Linux watch -Befehls. Die pywatch.watcher.Watcher -Klasse kann aufgefordert werden, eine Reihe von Dateien zu beobachten und eine Reihe von Befehlen zu geben, die ausgeführt werden, wenn sich eine dieser Dateien ändert. Es kann nur das Ereignis "Datei geändert" überwachen, da es auf die Abfrage der Statistik st_mtime angewiesen ist.

Bonus für Windows mit NTFS:

  • NTFS USN Journal

    Das NTFS-USN-Journal (Update Sequence Number) ist eine Funktion von NTFS, die Aufzeichnungen über Änderungen am Volume führt. Der Grund, warum es als ein Bonus aufgeführt ist, liegt darin, dass es im Gegensatz zu den anderen Einträgen keine spezielle Bibliothek ist, sondern eine auf dem NTFS-System vorhandene Funktion. Also, wenn Sie andere Windows-Dateisysteme (wie FAT, ReFS, etc ..) verwenden, gilt dies nicht.
    So wie es funktioniert, zeichnet das System alle Änderungen auf, die an dem Datenträger in der USN-Journaldatei vorgenommen wurden, wobei jeder Datenträger seine eigene Instanz hat. Jeder Datensatz im Change Journal enthält die USN, den Namen der Datei und Informationen darüber, was die Änderung war.

    Der Hauptgrund, warum diese Methode für diese Frage interessant ist, besteht darin, dass diese Methode im Gegensatz zu den meisten anderen Methoden die Erkennung eines file close -Ereignis ermöglicht, das als USN_REASON_CLOSE . Weitere Informationen mit einer vollständigen Liste von Ereignissen finden Sie in diesem MSDN-Artikel Eine vollständige Dokumentation zu USN Journaling finden Sie auf dieser MSDN-Seite .

    Es gibt mehrere Möglichkeiten, von Python aus auf das USN-Journal zuzugreifen. Die einzige ausgereifte Option scheint jedoch das ntfsjournal Modul.

Der "richtige" Weg für Windows:

  • Dateisystemfiltertreiber

    Wie auf der MSDN-Seite beschrieben :

      

    Ein Dateisystemfiltertreiber ist ein optionaler Treiber, der einen zusätzlichen Wert darstellt   oder ändert das Verhalten eines Dateisystems.Ein Dateisystemfiltertreiber   ist eine Kernelmoduskomponente, die als Teil der Windows-Anwendung ausgeführt wird.   Ein Dateisystemfiltertreiber kann E / A-Vorgänge für einen oder mehrere filtern   Dateisysteme oder Dateisystemvolumes. Abhängig von der Art des   Treiber, Filter kann bedeuten log, beobachten, ändern oder sogar verhindern. Typisch   Anwendungen für Dateisystemfiltertreiber sind Virenschutzprogramme   Dienstprogramme, Verschlüsselungsprogramme und hierarchische Speicherverwaltung   Systeme.

    Es ist keine einfache Aufgabe, einen Dateisystem-Filtertreiber zu implementieren, aber für jemanden, der es ausprobieren möchte, gibt es ein gutes Einführungs-Tutorial auf CodeProject .

    P.S. Weitere Informationen zu dieser Methode finden Sie @ ixe013 .

Multiplattform

  • Qts QFileSystemWatcher

    Die Klasse QFileSystemWatcher stellt eine Schnittstelle zur Überwachung von Dateien und Verzeichnissen für Änderungen bereit. Diese Klasse wurde in Qt 4.2 eingeführt.
    Leider ist seine Funktionalität ziemlich begrenzt, da es nur erkennen kann, wenn eine Datei geändert, umbenannt oder gelöscht wurde und wenn eine neue Datei zu einem Verzeichnis hinzugefügt wurde.

    Beispielverwendung:

    %Vor%
bosnjak 14.03.2014 13:43
quelle
3

Das Problem, mit dem Sie konfrontiert sind, ist nicht mit Python, sondern mit Windows. Es kann getan werden, aber Sie müssen einige nicht-trival C / C ++ Code dafür schreiben.

Eine Datei öffnen oder eine Datei schließen Benutzermodus Benachrichtigung existiert nicht in Benutzerland unter Windows. Aus diesem Grund haben die von anderen vorgeschlagenen Bibliotheken keine Benachrichtigung über die Dateischließung. In Windows ist die API zum Erkennen von Änderungen im Benutzerland ReadDirectoryChangesW . Sie erhalten eine Warnung eine der folgenden Benachrichtigungen :

  • FILE_ACTION_ADDED , wenn eine Datei zum Verzeichnis hinzugefügt wurde.
  • FILE_ACTION_REMOVED , wenn eine Datei aus dem Verzeichnis entfernt wurde.
  • FILE_ACTION_MODIFIED , wenn eine Datei geändert wurde. Dies kann eine Änderung des Zeitstempels oder der Attribute sein.
  • FILE_ACTION_RENAMED_OLD_NAME , wenn eine Datei umbenannt wurde und dies der alte Name ist.
  • FILE_ACTION_RENAMED_NEW_NAME , wenn eine Datei umbenannt wurde und dies der neue Name ist.

Keine Menge von Python kann ändern, was Windows Ihnen bietet.

Um eine Benachrichtigung zum Schließen einer Datei zu erhalten, installieren Tools wie Process Monitor eine Minifilter, der im Kern lebt , nahe der Spitze des anderen Filter wie EFS.

Um zu erreichen, was Sie wollen, müssten Sie:

  1. Installieren Sie einen Minifilter mit dem Code zum Senden von Ereignissen an das Benutzerland. Verwenden Sie Microsofts Minispy-Beispiel , es ist stabil und schnell.
  2. Konvertieren Sie den Code aus dem Programm user in eine Python-Erweiterung ( minispy.pyd ), die einen Generator freigibt, der die Ereignisse erzeugt. Das ist der schwierige Teil, ich werde darauf zurückkommen.
  3. Sie müssen Ereignisse herausfiltern, Sie werden nicht glauben, dass der IO-Anteil auf einer leeren Windows-Box läuft!
  4. Ihr Python-Programm kann dann Ihre Erweiterung importieren und ihr Ding machen.

Das Ganze sieht ungefähr so ​​aus:

Natürlich können Sie EFS über NTFS haben, das ist nur um zu zeigen, dass Ihr Minifilter über allem steht.

Die harten Teile:

  • Ihr Minifilter muss von einer Behörde, der Microsoft vertraut, digital signiert sein. Vergebung kommt mir in den Sinn, aber es gibt andere.
  • Debugging erfordert eine separate (virtuelle) Maschine, aber Sie können Ihre Schnittstelle einfach zum Mock machen.
  • Sie müssen den Minifilter mit einem Konto installieren, das über Administratorrechte verfügt. Jeder Benutzer kann Ereignisse lesen.
  • Sie werden sich selbst mit Multi-Usern auseinandersetzen müssen. Es gibt nur einen Minifilter für viele Benutzer.
  • Sie müssen das Benutzerprogramm vom MiniSpy-Beispiel in eine DLL konvertieren, die Sie mit einer Python-Erweiterung umschließen.

Die letzten beiden sind am schwersten.

    
ixe013 25.03.2014 21:19
quelle
1

Sie können Pyfanotyfi oder Butter .

Ich denke, Sie finden diesen Link sehr nützlich: Linux-Dateisystem Ereignisse mit C, Python und Ruby

Dort finden Sie ein Beispiel dafür, genau das zu tun, was Sie wollen (mit pyinotify ), das ist der Code:

%Vor%     
Raydel Miranda 14.03.2014 13:45
quelle
0

Ich habe kein Paket gefunden, das die Ereignisse open und close unter Windows erfasst. Wie andere bereits erwähnt haben, ist pyinotify eine hervorragende Option für Linux-basierte Betriebssysteme.

Da ich nicht auf das geschlossene Event achten konnte, entschied ich mich für das modifizierte Event. Es ist eine sehr "nachträgliche" Art der Lösung (dh ich kann nicht pausieren, bis ich sehe, dass eine Datei geschlossen ist). Aber das hat überraschend gut funktioniert.

Ich habe das Watchdog -Paket verwendet. Der folgende Code stammt aus der Beispiel Implementierung und überwacht das aktuelle Verzeichnis, wenn Sie nicht bestehen ein Pfad in der Befehlszeile, andernfalls überwacht er den Pfad, den Sie übergeben.

Beispielaufruf: python test.py oder python test.py C:\Users\Administrator\Desktop

%Vor%

Dieser Code zeigt Ihnen, wenn Dateien erstellt, geändert, gelöscht oder umbenannt / verschoben werden. Sie können filtern, indem Sie einfach nach dem on_modified Ereignis suchen.

    
Andy 24.03.2014 19:34
quelle