2013-04-15 5 views
0
void TestDirChanges(LPCWSTR path) 
{ 
/* 
FileName member of FILE_NOTIFY_INFORMATION has only one WCHAR according to definition. Most likely, this field will have more characters. 
So the expected size of one item is (sizeof(FILE_NOTIFY_INFORMATION) + MAX_PATH * sizeof(WCHAR)). 
Prepare buffer for 256 items. 
*/ 
char buf[256 * (sizeof(FILE_NOTIFY_INFORMATION) + MAX_PATH * sizeof(WCHAR))] = {0}; 
DWORD bytesReturned = 0; 
BOOL result = FALSE; 
FILE_NOTIFY_INFORMATION *fni = NULL; 

HANDLE hDir = CreateFile(path, 
    FILE_LIST_DIRECTORY | STANDARD_RIGHTS_READ, 
    FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, 
    NULL, 
    OPEN_EXISTING, 
    FILE_FLAG_BACKUP_SEMANTICS, 
    NULL); 

if (!hDir || hDir == INVALID_HANDLE_VALUE) 
{ 
    wprintf(L"CreateFile failed\n"); 
    return; 
} 

while (1) 
{ 
    result = ReadDirectoryChangesW(hDir, 
     buf, 
     sizeof(buf)/sizeof(*buf), 
     TRUE, /* monitor the entire subtree */ 
     FILE_NOTIFY_CHANGE_FILE_NAME | 
      FILE_NOTIFY_CHANGE_DIR_NAME | 
      FILE_NOTIFY_CHANGE_ATTRIBUTES | 
      FILE_NOTIFY_CHANGE_SIZE | 
      FILE_NOTIFY_CHANGE_LAST_WRITE | 
      FILE_NOTIFY_CHANGE_LAST_ACCESS | 
      FILE_NOTIFY_CHANGE_CREATION | 
      FILE_NOTIFY_CHANGE_SECURITY, 
     &bytesReturned, 
     NULL, 
     NULL); 

    if (result && bytesReturned) 
    { 
     wchar_t filename[MAX_PATH]; 
     wchar_t action[256]; 
     for (fni = (FILE_NOTIFY_INFORMATION*)buf; fni;) 
     { 
      switch (fni->Action) 
      { 
      case FILE_ACTION_ADDED: 
       wcscpy_s(action, sizeof(action)/sizeof(*action), L"File added:"); 
       break; 

      case FILE_ACTION_REMOVED: 
       wcscpy_s(action, sizeof(action)/sizeof(*action), L"File removed:"); 
       break; 

      case FILE_ACTION_MODIFIED: 
       wcscpy_s(action, sizeof(action)/sizeof(*action), L"File modified:"); 
       break; 

      case FILE_ACTION_RENAMED_OLD_NAME: 
       wcscpy_s(action, sizeof(action)/sizeof(*action), L"File renamed, was:"); 
       break; 

      case FILE_ACTION_RENAMED_NEW_NAME: 
       wcscpy_s(action, sizeof(action)/sizeof(*action), L"File renamed, now is:"); 
       break; 

      default: 
       swprintf_s(action, sizeof(action)/sizeof(*action), L"Unkonwn action: %ld. File name is:", fni->Action); 
      } 

      if (fni->FileNameLength) 
      { 
       wcsncpy_s(filename, MAX_PATH, fni->FileName, fni->FileNameLength/2); 
       filename[fni->FileNameLength/2] = 0; 
       wprintf(L"%s '%s'\n", action, filename); 
      } 
      else 
      { 
       wprintf(L"%s <EMPTY>\n", action); 
      }     

      if (fni->NextEntryOffset) 
      { 
       char *p = (char*)fni; 
       fni = (FILE_NOTIFY_INFORMATION*)(p + fni->NextEntryOffset); 
      } 
      else 
      { 
       fni = NULL; 
      } 
     } 
    } 
    else 
    { 
     wprintf(L"ReadDirectoryChangesW failed\n"); 
    } 
} 

CloseHandle(hDir); 
} 

Мой код работает хорошо на WIN32 Console, но когда я использую его в проекте WIN32, ReadDirectoryChangesW не работает. Он работает, и мое программирование перестает работать. Помогите пожалуйста, С наилучшими пожеланиями,Ошибка ReadDirectoryChangesW в проекте WIN32 API?

+1

Какая ошибка? – Rohan

+0

Когда я запускаю его на WIN32 API Project not Console, моя программа перестает работать. Я не могу отключить его. –

+2

Как вы ожидаете «отключить его»? У вас бесконечный цикл (скорее всего, не в отдельном потоке). –

ответ

1

Похоже, вы блокируете поток пользовательского интерфейса в проекте win32, и приложение кажется замороженным, и оно не будет реагировать. Запустите рабочий поток и сделайте материал внутри рабочего потока.

Я думаю, что лучше использовать API-интерфейс уведомлений, например SHChangeNotifyRegister, который сообщит вам, произошли ли какие-либо изменения в каталоге, а затем вы можете прочитать каталог, а не делать это в цикле while. Также есть приложение unicode? Вы используете ReadDirectoryChangesW?

http://msdn.microsoft.com/en-us/library/windows/desktop/bb762120.aspx

+0

Я пытаюсь использовать ReadDirectoryChangesW. Можете привести мне пример о SHChangeNotifyRegister –

+0

Вы можете прочитать документацию 'SHChangeNotifyRegister' в msdn. Это поможет вам получить уведомление, если что-то изменилось, так что вы избавитесь от цикла while. Как только вы получите уведомление, вам нужно пробовать сделать то же самое, что и прочитанный каталог, который изменился. http://msdn.microsoft.com/en-us/library/windows/desktop/bb762120(v=vs.85).aspx В документации у них есть ссылка на образец SDK –

+0

Я использую WIN32 API C/C++. Это работает? –