就像听起来一样,我正在尝试ReadDirectoryChangesW
与 IO Completion 异步,但它不起作用,特别是GetLastError
反复返回 258 (GetQueuedCompletionStatus
超时)。
我有结构:
typedef struct dirinfo_struct
{
HANDLE hDirFH; // directory handle
OVERLAPPED Overlapped; // overlapped storage
int len_buffer; // buffer length
wchar_t* buffer; // buffer itself
wchar_t* directory_name; // target name
} dirinfo_t;
typedef struct dirmon_struct
{
HANDLE hDirOPPort; // handle to the IO port.
dirinfo_t* dirinfo; // pointer to the struct above.
} dirmon_t;
用于存储相关信息。这是初始化的:
dirinfo_t* t = malloc(1*sizeof(dirinfo_t));
dirmon_t* d = malloc(1*sizeof(dirmon_t));
dirinfo_init(t); // does t->buffer = malloc(8192*sizeof(wchar_t));
然后我创建我的目录句柄和 com 端口:
t->hDirFH = CreateFile(L"C:\\test",
FILE_LIST_DIRECTORY,
FILE_SHARE_READ|FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OVERLAPPED,
NULL);
d->dirinfo = t;
d->hDirOPPort = CreateIoCompletionPort(d->dirinfo->hDirFH,
NULL,
(ULONG_PTR)(d->dirinfo),
1);
然后我通过 d 将此信息传递给一个新线程。现在在所说的新线程上,我有:
bResultQ = GetQueuedCompletionStatus(d->hDirOPPort, lpBytes,
(ULONG_PTR*)d->dirinfo,
lpOverlapped, 1000);
if ( bResultQ )
{
bResultR = ReadDirectoryChangesW(d->dirinfo->hDirFH,
(void*)d->dirinfo->buffer,
8192, TRUE,
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,
lpReadDirBytes,
&d->dirinfo->Overlapped,
NULL );
}
else
{
printf("GetQueuedCompletionStatus(): Failed, ");
errorcode = GetLastError();
printf("Error Code %d\n", errorcode);
Sleep(500);
}
所以我把它设置为运行,我很高兴得到超时(258个错误),因为目录没有改变。但是,即使我更改了目录,我仍然会收到错误消息;换句话说,这些改动没有被采纳。这让我相信我的设置不正确。
有任何想法吗?
注意事项:
- 具有讽刺意味的是,这最终将通过 pywin32 转换为 Python。但是,在我了解这应该如何在 C 中工作之前,我不会去那里。
- 同步
ReadDirectoryChangesW
不是一个选项。如果没有事件被触发,我需要这个线程超时,以便它可以检查它是否应该仍在运行。 - 我专门用 C 编写,而不是 C++。
FindFirstChangeNotification
等等也不是一个选项——我不想不断地比较目录列表来找出发生了什么变化。
其他注意事项:
- 目录存在,该句柄不为 NULL。对于 comport 句柄也是如此。
- 一切都被传递到线程
我从代码项目中查看了CDirectoryChangeWatcher,但是除了使用 C++ 和更多线程之外,我看不出我在做什么不同。如果我遗漏了什么,请随时指出!
输出,如果有帮助的话,基本上是重复的,不管我改变了多少有问题的目录。
GetQueuedCompletionStatus(): Failed, Error Code 258