zoukankan      html  css  js  c++  java
  • ReadDirectoryChangesW 监控文件夹 (一个简单的监控示例程序)(文件被修改了,也可以探测到)

    [cpp] view plain copy
     
    1. // .h文件  
    2. #pragma once  
    3.   
    4. typedef void (*PFN_NotifyAction)(DWORD dwAction, LPWSTR szFile, DWORD dwLength);  
    5.   
    6. class CDirectoryWatch  
    7. {  
    8. public:  
    9.     CDirectoryWatch(void);  
    10.     virtual ~CDirectoryWatch(void);  
    11.   
    12. public:  
    13.     BOOL StartDirectoryWatch(LPCTSTR lpszDirectory, PFN_NotifyAction pFn_NotifyAction);  
    14.     BOOL StopDirectoryWatch(void);  
    15.   
    16. private:  
    17.     static UINT __cdecl ThreadProc(LPVOID lParam);  
    18.     static UINT __cdecl DirectoryWatch(LPVOID lParam);  
    19.   
    20. private:  
    21.     HANDLE m_hFile;  
    22.     CWinThread* m_pThread;  
    23.     TCHAR m_szDirectory[MAX_PATH];  
    24. };  
    [cpp] view plain copy
     
    1. // .cpp文件  
    2. #include "StdAfx.h"  
    3. #include "DirectoryWatch.h"  
    4. #include <strsafe.h>  
    5.   
    6. typedef enum  
    7. {  
    8.     MSG_STARTWATCH = (WM_USER + 0x11),  
    9.     MSG_STOPWATCH,  
    10.     MSG_EXITTHREAD  
    11. };  
    12.   
    13. #define MAX_BUFFER_SIZE (1024)  
    14.   
    15. typedef struct _tagWATCHPARAMETERS  
    16. {  
    17.     _tagWATCHPARAMETERS()  
    18.     {  
    19.         hFile = INVALID_HANDLE_VALUE;  
    20.         hEvent = NULL;  
    21.         memset(&ol, 0, sizeof(OVERLAPPED));  
    22.         pBuffer = NULL;  
    23.         dwBufferSize = 0;  
    24.         bExit = FALSE;  
    25.         pFn_NotifyAction = NULL;  
    26.     }  
    27.     HANDLE hFile;  
    28.     HANDLE hEvent;  
    29.     OVERLAPPED ol;  
    30.     BYTE* pBuffer;  
    31.     DWORD dwBufferSize;  
    32.     BOOL bExit;  
    33.     PFN_NotifyAction pFn_NotifyAction;  
    34. }WATCH_PARAMETERS, *PWATCH_PARAMETERS;  
    35.   
    36. CDirectoryWatch::CDirectoryWatch() : m_hFile(INVALID_HANDLE_VALUE), m_pThread(NULL)  
    37. {  
    38.     memset(m_szDirectory, 0, sizeof(m_szDirectory));  
    39.   
    40.     m_pThread = AfxBeginThread(ThreadProc, NULL, 0, CREATE_SUSPENDED, 0, NULL);  
    41.     if(NULL == m_pThread)  
    42.     {  
    43.         TRACE("Error Code : %d ", GetLastError());  
    44.         return ;  
    45.     }  
    46.     m_pThread->m_bAutoDelete = FALSE;  
    47.     m_pThread->ResumeThread();  
    48. }  
    49.   
    50.   
    51. CDirectoryWatch::~CDirectoryWatch()  
    52. {  
    53.     if(INVALID_HANDLE_VALUE != m_hFile)  
    54.     {  
    55.         CloseHandle(m_hFile);  
    56.         m_hFile = INVALID_HANDLE_VALUE;  
    57.     }  
    58.   
    59.     if((NULL != m_pThread) && (NULL != m_pThread->m_hThread))  
    60.     {  
    61.   
    62.         m_pThread->PostThreadMessage(MSG_EXITTHREAD, 0, 0);  
    63.         WaitForSingleObject(m_pThread->m_hThread, INFINITE);  
    64.         delete m_pThread;  
    65.         m_pThread = NULL;  
    66.     }  
    67. }  
    68.   
    69. BOOL CDirectoryWatch::StartDirectoryWatch(LPCTSTR lpszDirectory, PFN_NotifyAction pFn_NotifyAction)  
    70. {  
    71.     if(NULL == m_pThread)  
    72.     {  
    73.         return FALSE;  
    74.     }  
    75.   
    76.     if(NULL == lpszDirectory)  
    77.     {  
    78.         return FALSE;  
    79.     }  
    80.   
    81.     if(NULL == pFn_NotifyAction)  
    82.     {  
    83.         return FALSE;  
    84.     }  
    85.   
    86.     if(!PathFileExists(lpszDirectory))  
    87.     {  
    88.         TRACE("Error Code : %d ", GetLastError());  
    89.         return FALSE;  
    90.     }  
    91.   
    92.     if(!PathIsDirectory(lpszDirectory))  
    93.     {  
    94.         TRACE("Error Code : %d ", GetLastError());  
    95.         return FALSE;  
    96.     }  
    97.   
    98.     if(0 == _tcslen(m_szDirectory))  
    99.     {  
    100.         StringCchPrintf(m_szDirectory, _countof(m_szDirectory), _T("%s"), lpszDirectory);  
    101.     }  
    102.     else if(CSTR_EQUAL != CompareStringOrdinal(m_szDirectory, -1, lpszDirectory, -1, TRUE))  
    103.     {  
    104.         TRACE("Not Change Directory. ");  
    105.         return FALSE;  
    106.     }  
    107.   
    108.     if(INVALID_HANDLE_VALUE == m_hFile)  
    109.     {  
    110.         m_hFile = CreateFile(lpszDirectory, FILE_LIST_DIRECTORY, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,  
    111.             NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OVERLAPPED, NULL);  
    112.         if(INVALID_HANDLE_VALUE == m_hFile)  
    113.         {  
    114.             TRACE("Error Code : %d ", GetLastError());  
    115.             return FALSE;  
    116.         }  
    117.     }  
    118.   
    119.     return m_pThread->PostThreadMessage(MSG_STARTWATCH, (WPARAM)m_hFile, (LPARAM)pFn_NotifyAction);  
    120. }  
    121.   
    122. BOOL CDirectoryWatch::StopDirectoryWatch()  
    123. {  
    124.     if(NULL != m_pThread)  
    125.     {  
    126.         return m_pThread->PostThreadMessage(MSG_STOPWATCH, 0, 0);  
    127.     }  
    128.   
    129.     return FALSE;  
    130. }  
    131.   
    132. UINT __cdecl CDirectoryWatch::DirectoryWatch(LPVOID lParam)  
    133. {  
    134.     WATCH_PARAMETERS* pParam = (WATCH_PARAMETERS*)lParam;  
    135.     if(NULL == pParam)  
    136.     {  
    137.         return 0;  
    138.     }  
    139.     HANDLE& hFile = pParam->hFile;  
    140.     BYTE* pBuffer = pParam->pBuffer;  
    141.     DWORD dwBufferSize = pParam->dwBufferSize;  
    142.     OVERLAPPED& ol = pParam->ol;  
    143.     HANDLE& hEvent = pParam->hEvent;  
    144.     BOOL& bExit = pParam->bExit;  
    145.     PFN_NotifyAction pFn_NotifyAction = pParam->pFn_NotifyAction;  
    146.     DWORD dwBytesReturn = 0;  
    147.     DWORD dwRet = WAIT_FAILED;  
    148.     DWORD dwOffSet = 0;  
    149.     TCHAR szFile[MAX_PATH] = {0};  
    150.     while(TRUE)  
    151.     {  
    152.         if(WAIT_OBJECT_0 != WaitForSingleObject(hEvent, INFINITE))  
    153.         {  
    154.             TRACE("Error Code : %d ", GetLastError());  
    155.             break;  
    156.         }  
    157.   
    158.         if(bExit)  
    159.         {  
    160.             break;  
    161.         }  
    162.       
    163.         if(!ReadDirectoryChangesW(hFile, pBuffer, dwBufferSize, TRUE,   
    164.             FILE_NOTIFY_CHANGE_FILE_NAME | FILE_NOTIFY_CHANGE_DIR_NAME | FILE_NOTIFY_CHANGE_ATTRIBUTES  
    165.             | FILE_NOTIFY_CHANGE_SIZE | FILE_NOTIFY_CHANGE_LAST_WRITE | FILE_NOTIFY_CHANGE_LAST_ACCESS  
    166.             | FILE_NOTIFY_CHANGE_CREATION | FILE_NOTIFY_CHANGE_SECURITY, &dwBytesReturn, &ol, NULL))  
    167.         {  
    168.             TRACE("Error Code : %d ", GetLastError());  
    169.             break;  
    170.         }  
    171.         if(!GetOverlappedResult(hFile, &ol, &dwBytesReturn, TRUE))  
    172.         {  
    173.             TRACE("Error Code : %d ", GetLastError());  
    174.             break;  
    175.         }  
    176.         FILE_NOTIFY_INFORMATION* pFileNotify = (FILE_NOTIFY_INFORMATION*)pBuffer;  
    177.           
    178.         do   
    179.         {  
    180.             if(pFn_NotifyAction && (WAIT_OBJECT_0 == WaitForSingleObject(hEvent, 0)))  
    181.             {  
    182.                 pFn_NotifyAction(pFileNotify->Action, pFileNotify->FileName, (pFileNotify->FileNameLength) / sizeof(WCHAR));  
    183.             }  
    184.   
    185.             dwOffSet = pFileNotify->NextEntryOffset;  
    186.             pFileNotify = (FILE_NOTIFY_INFORMATION*)((BYTE*)pFileNotify + dwOffSet);  
    187.         } while (dwOffSet);  
    188.     }  
    189.     TRACE0("DirectoryWatch Thread Exit ...  ");  
    190.     return 0;  
    191. }  
    192.   
    193. UINT __cdecl CDirectoryWatch::ThreadProc(LPVOID lParam)  
    194. {  
    195.     WATCH_PARAMETERS* pParam = new WATCH_PARAMETERS;  
    196.   
    197.     if(NULL == pParam)  
    198.     {  
    199.         goto __CLEANUP__;  
    200.     }  
    201.   
    202.     BYTE* pBuffer = new BYTE[MAX_BUFFER_SIZE];  
    203.     if(NULL == pBuffer)  
    204.     {  
    205.         goto __CLEANUP__;  
    206.     }  
    207.     memset(pBuffer, 0, MAX_BUFFER_SIZE);  
    208.     pParam->pBuffer = pBuffer;  
    209.     pParam->dwBufferSize = MAX_BUFFER_SIZE;  
    210.     HANDLE hWatchEvent  = CreateEvent(NULL, TRUE, FALSE, NULL);  
    211.     if(NULL == hWatchEvent)  
    212.     {  
    213.         goto __CLEANUP__;  
    214.     }  
    215.     pParam->ol.hEvent = hWatchEvent;  
    216.     CWinThread* pThread = NULL;  
    217.     HANDLE hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);  
    218.     if(NULL == hEvent)  
    219.     {  
    220.         goto __CLEANUP__;  
    221.     }  
    222.     pParam->hEvent = hEvent;  
    223.     MSG msg;  
    224.     while(GetMessage(&msg, NULL, 0, 0))  
    225.     {  
    226.         switch(msg.message)  
    227.         {  
    228.         case MSG_STARTWATCH:  
    229.             {  
    230.                 HANDLE hFile = (HANDLE)(msg.wParam);  
    231.                 PFN_NotifyAction pFn_NotifyAction = (PFN_NotifyAction)(msg.lParam);  
    232.                 if((INVALID_HANDLE_VALUE == hFile) && (NULL == pFn_NotifyAction))  
    233.                 {  
    234.                     break;  
    235.                 }  
    236.                 if(NULL == pThread)  
    237.                 {  
    238.                     pParam->hFile = hFile;  
    239.                     pParam->pFn_NotifyAction = pFn_NotifyAction;  
    240.                     pThread = AfxBeginThread(DirectoryWatch, (LPVOID)pParam, 0, CREATE_SUSPENDED, NULL);  
    241.                     if(NULL == pThread)  
    242.                     {  
    243.                         goto __CLEANUP__;  
    244.                     }  
    245.                     pThread->m_bAutoDelete = FALSE;  
    246.                     pThread->ResumeThread();  
    247.                 }                 
    248.                 SetEvent(hEvent);  
    249.             }  
    250.             break;  
    251.   
    252.         case MSG_STOPWATCH:  
    253.             {  
    254.                 ResetEvent(hEvent);  
    255.             }  
    256.             break;  
    257.   
    258.         case MSG_EXITTHREAD:  
    259.             {  
    260.                 SetEvent(hEvent);  
    261.                 pParam->bExit = FALSE;  
    262.                   
    263.                 if((NULL != pThread) && (NULL != pThread->m_hThread))  
    264.                 {  
    265.                     WaitForSingleObject(pThread->m_hThread, INFINITE);  
    266.                     delete pThread;  
    267.                     pThread = NULL;  
    268.                 }  
    269.                 goto __CLEANUP__;  
    270.             }  
    271.               
    272.         default:  
    273.             break;  
    274.         }  
    275.         TranslateMessage(&msg);  
    276.         DispatchMessage(&msg);  
    277.     }  
    278.   
    279. __CLEANUP__:  
    280.     if(NULL != hWatchEvent)  
    281.     {  
    282.         CloseHandle(hWatchEvent);  
    283.         hWatchEvent = NULL;  
    284.     }  
    285.     if(NULL != pBuffer)  
    286.     {  
    287.         delete[] pBuffer;  
    288.         pBuffer = NULL;  
    289.     }  
    290.     if(NULL != pParam)  
    291.     {  
    292.         delete pParam;  
    293.         pParam = NULL;  
    294.     }  
    295.     TRACE0("ThreadProc Thread Exit ... ");  
    296.     return 0;  
    297. }  
    [cpp] view plain copy
     
    1. // 测试代码  
    2.   
    3. #include "stdafx.h"  
    4.   
    5. #include "DirectoryWatch.h"  
    6.   
    7. void NotifyAction(DWORD dwAction, LPWSTR szFile, DWORD dwLength)  
    8. {  
    9.     switch(dwAction)  
    10.     {  
    11.     case FILE_ACTION_ADDED:  
    12.         wprintf(L"FILE_ACTION_ADDED:  ");  
    13.         break;  
    14.   
    15.     case FILE_ACTION_REMOVED:  
    16.         wprintf(L"FILE_ACTION_REMOVED:  ");  
    17.         break;  
    18.   
    19.     case FILE_ACTION_MODIFIED:  
    20.         wprintf(L"FILE_ACTION_MODIFIED:  ");  
    21.         break;  
    22.   
    23.     case FILE_ACTION_RENAMED_OLD_NAME:  
    24.         wprintf(L"FILE_ACTION_RENAMED_OLD_NAME:  ");  
    25.         break;  
    26.   
    27.     case FILE_ACTION_RENAMED_NEW_NAME:  
    28.         wprintf(L"FILE_ACTION_RENAMED_NEW_NAME:  ");  
    29.         break;  
    30.   
    31.     default:  
    32.         break;  
    33.     }  
    34.     WCHAR szPath[MAX_PATH] = {0};  
    35.     wmemcpy(szPath, szFile, min(dwLength, MAX_PATH));  
    36.     wprintf(L"%s ", szPath);  
    37. }  
    38.   
    39. int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])  
    40. {  
    41.     CDirectoryWatch watch;  
    42.     wprintf(L"Start Directory Watch ... ");  
    43.     watch.StartDirectoryWatch(_T("F:\11"), NotifyAction);  
    44.     Sleep(30 * 1000);     
    45.     watch.StopDirectoryWatch();  
    46.     wprintf(L"Stop Directory Watch ... ");  
    47.   
    48.     Sleep(10 * 1000);  
    49.   
    50.     wprintf(L"Start Directory Watch ... ");  
    51.     watch.StartDirectoryWatch(_T("F:\11"), NotifyAction);  
    52.     Sleep(30 * 1000);     
    53.     watch.StopDirectoryWatch();  
    54.     wprintf(L"Stop Directory Watch ... ");  
    55.     Sleep(30 * 1000);  
    56.     wprintf(L"Process Exit ... ");  
    57.     return 0;  
    58. }  

    效果如下图所示:

    http://blog.csdn.net/visualeleven/article/details/7562014

  • 相关阅读:
    SSH 远程执行任务
    redmine + git
    progit-cn
    bash keys
    性能优化挑战重重,鲲鹏 HPC 如何突破算力桎梏?
    基因组实现自动AI建模,华为云助力科研人员探索生命奥秘
    【华为云技术分享】从零搭建一个灰度发布环境
    全面拥抱 FastApi — 多应用程序项目结构规划
    【华为云技术分享】物体检测yolo3算法 学习笔记(1)
    【华为云技术分享】物体检测yolo3算法 学习笔记2
  • 原文地址:https://www.cnblogs.com/findumars/p/6001732.html
Copyright © 2011-2022 走看看