Winapi 异步ReadDirectoryChangesW失败,错误为\u参数无效
我已经设法同步使用了Winapi 异步ReadDirectoryChangesW失败,错误为\u参数无效,winapi,asynchronous,Winapi,Asynchronous,我已经设法同步使用了ReadDirectoryChangesW,但是当我尝试使用完成端口时,ReadDirectoryChangesW总是返回错误\u无效\u参数。我想我的代码中应该有一些明显的错误,但我无法理解 我的代码是基于 正如Hans Passant善意地提醒的那样,他已经说过,如果目录与完成端口关联,则不能使用完成例程。在本例中,我通过等待完成端口解决了问题,即,ReadDirectoryChangesW(…,&overlapped,0) 完整的代码如下 while (true) {
ReadDirectoryChangesW
,但是当我尝试使用完成端口时,ReadDirectoryChangesW
总是返回错误\u无效\u参数
。我想我的代码中应该有一些明显的错误,但我无法理解
我的代码是基于
正如Hans Passant善意地提醒的那样,他已经说过,如果目录与完成端口关联,则不能使用完成例程。在本例中,我通过等待完成端口解决了问题,即,
ReadDirectoryChangesW(…,&overlapped,0)代码>
完整的代码如下
while (true) {
OVERLAPPED overlapped;
memset(&overlapped,0,sizeof(overlapped));
BOOL success = ReadDirectoryChangesW(h,
&buffer[0],
4096*sizeof(DWORD),
FALSE, notifyFilter, 0, &overlapped,0);
if (!success) {
if (GetLastError()==ERROR_INVALID_HANDLE) {
//asynchronously closed by cancel
CloseHandle(p); //close completion port
return 0;
} else {
CloseHandle(h); //close directory handle
CloseHandle(p); //close completion port
return 1;
}
}
DWORD di;
LPOVERLAPPED lpOverlapped;
if (!GetQueuedCompletionStatus(p,&bytesReturned,&di,&lpOverlapped,1000)) {
int ret;
if (GetLastError()==WAIT_TIMEOUT) {
if (GetFileAttributes(directory)!=INVALID_FILE_ATTRIBUTES) {
continue; //timeout
} else {
//directory has been deleted or renamed
ret=0;
}
} else {
//other failure
ret=1;
}
CloseHandle(h); //close directory handle
CloseHandle(p); //close completion port
return ret;
}
char* ptr = (char*)&buffer[0];
char* end = ptr+bytesReturned;
while (ptr<end) {
FILE_NOTIFY_INFORMATION *info = (FILE_NOTIFY_INFORMATION*) ptr;
//process FILE_NOTIFY_INFORMATION
ptr+=info->NextEntryOffset;
if (!info->NextEntryOffset) break;
}
}
while(true){
重叠;
memset(&overlapped,0,sizeof(overlapped));
BOOL success=ReadDirectoryChangesW(h,
&缓冲区[0],
4096*sizeof(德沃德),
FALSE,notifyFilter,0,重叠(&O),0);
如果(!成功){
if(GetLastError()==错误\u无效\u句柄){
//通过取消异步关闭
CloseHandle(p);//关闭完成端口
返回0;
}否则{
CloseHandle(h);//关闭目录句柄
CloseHandle(p);//关闭完成端口
返回1;
}
}
德沃德·迪;
lp重叠lp重叠;
如果(!GetQueuedCompletionStatus(p,&bytesReturned,&di,&lpOverlapped,1000)){
int ret;
如果(GetLastError()==等待\u超时){
如果(GetFileAttributes(目录)!=无效的文件属性){
继续;//超时
}否则{
//目录已被删除或重命名
ret=0;
}
}否则{
//其他故障
ret=1;
}
CloseHandle(h);//关闭目录句柄
CloseHandle(p);//关闭完成端口
返回ret;
}
char*ptr=(char*)和缓冲区[0];
char*end=ptr+bytes返回;
while(ptrNextEntryOffset;
如果(!info->nexteryOffset)中断;
}
}
您没有显示notifyFilter和myFileIOCompletionRoutine定义。CreateIoCompletionPort返回NULL如果失败,则测试不正确。可能CreateIoCompletionPort失败?@AlexFarber,谢谢您指出,但CreateIoCompletionPort返回有效句柄。@AlexFarber我添加了notifyFilter.myFileIOCompletionRout的声明ine目前什么都不做,即MSDN库文章中的重要说明:要通过完成例程接收通知,请**不要**将目录与完成端口关联。
如果您帮助很大,请删除CreateIoCompletionPort()调用。
while (true) {
OVERLAPPED overlapped;
memset(&overlapped,0,sizeof(overlapped));
BOOL success = ReadDirectoryChangesW(h,
&buffer[0],
4096*sizeof(DWORD),
FALSE, notifyFilter, 0, &overlapped,0);
if (!success) {
if (GetLastError()==ERROR_INVALID_HANDLE) {
//asynchronously closed by cancel
CloseHandle(p); //close completion port
return 0;
} else {
CloseHandle(h); //close directory handle
CloseHandle(p); //close completion port
return 1;
}
}
DWORD di;
LPOVERLAPPED lpOverlapped;
if (!GetQueuedCompletionStatus(p,&bytesReturned,&di,&lpOverlapped,1000)) {
int ret;
if (GetLastError()==WAIT_TIMEOUT) {
if (GetFileAttributes(directory)!=INVALID_FILE_ATTRIBUTES) {
continue; //timeout
} else {
//directory has been deleted or renamed
ret=0;
}
} else {
//other failure
ret=1;
}
CloseHandle(h); //close directory handle
CloseHandle(p); //close completion port
return ret;
}
char* ptr = (char*)&buffer[0];
char* end = ptr+bytesReturned;
while (ptr<end) {
FILE_NOTIFY_INFORMATION *info = (FILE_NOTIFY_INFORMATION*) ptr;
//process FILE_NOTIFY_INFORMATION
ptr+=info->NextEntryOffset;
if (!info->NextEntryOffset) break;
}
}