在不阻塞的情况下捕获文件安全权限的变化

catch change in security permission of file without blocking

我想捕获文件安全权限的变化而不阻塞,直到发生变化,就像发生变化时弹出的事件。

我也不想安装任何第三方模块或软件。

这个的主要需求是在一些win32模块或者内置模块中。

我目前正在通过此功能观察安全更改:

    import win32con, win32file
    def security_watcher():

        specific_file = "specific.ini"
        path_to_watch = "." 
        FILE_LIST_DIRECTORY = 0x0001
        hDir = win32file.CreateFile(path_to_watch,
                                    FILE_LIST_DIRECTORY,
                                    win32con.FILE_SHARE_READ | 
                                    win32con.FILE_SHARE_WRITE | 
                                    win32con.FILE_SHARE_DELETE,
                                    None,
                                    win32con.OPEN_EXISTING,
                                    win32con.FILE_FLAG_BACKUP_SEMANTICS,
                                    None)
        results = win32file.ReadDirectoryChangesW(hDir,
                                                  1024,
                                                  False,
                                                  win32con.FILE_NOTIFY_CHANGE_SECURITY,
                                                  None,
                                                  None)
        print results
        for action, file_name in results:
            if file_name == specific_file:
               # wake another function to do something about that

注意:我需要它是非阻塞的,因为我在 GUI 应用程序中使用这个函数,它会冻结 GUI。

如果您不介意(或无法避免)增加一些线程开销,您可以启动一个单独的进程或线程来等待对您已有的 win32.ReadDirectoryChangesW() 的阻塞调用。当它收到更改时,它会将结果写入与 GUI 的主线程共享的管道。

您的 GUI 可以在代码中的适当位置(大概是您现在调用 win32file.ReadDirectoryChangesW() 的位置)定期执行非阻塞读取。请确保在读取之间稍等片刻,否则您的应用程序将 100% 的时间花在非阻塞读取上。

您可以在 this answer 中了解如何以 OS 独立的方式在管道上设置非阻塞读取。最后一点将如下所示:

try:  
    results = q.get_nowait()
except Empty:
    pass
else:  
    for line in results.splitlines():
        # Parse and use your result format
        ...
        if file_name == specific_file:
            ...