1. 他のプロセスがやってるダウンロード始まった?終わった?
他のプロセスがおこなっている外部からのファイルダウンロード完了を、これで検知できるかなぁ。。。
(1) 特定のフォルダーにファイルが作成されたかどうか調べる
char pdir[MAX_PATH]{};
char cdir[MAX_PATH]{};
strcpy(pdir, HomeFolderName);
GetCurrentDirectory(MAX_PATH, cdir);
HANDLE hdir=CreateFile(pdir, FILE_LIST_DIRECTORY,
FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS|FILE_FLAG_OVERLAPPED, NULL);
WCHAR lpBuffer[MAX_PATH]{};
DWORD dwNotifyFilter=FILE_NOTIFY_CHANGE_FILE_NAME;
HANDLE hEventF=CreateEvent(NULL, TRUE, FALSE, NULL);
OVERLAPPED olp{}; olp.hEvent=hEventF;
if(hdir!=INVALID_HANDLE_VALUE){
ReadDirectoryChangesW(hdir, lpBuffer, MAX_PATH, TRUE, dwNotifyFilter, NULL, &olp, NULL);
}
for(;;){
if(hdir!=INVALID_HANDLE_VALUE){
if(WaitForSingleObject(hEventF, 0)!=WAIT_TIMEOUT){
ResetEvent(hEventF);
DWORD retsize=0;
GetOverlappedResult(hdir, &olp, &retsize, FALSE);
FILE_NOTIFY_INFORMATION *lpInfomation=(FILE_NOTIFY_INFORMATION *)&lpBuffer[0];
if(lpInfomation!=NULL){
if(lpInfomation->Action==FILE_ACTION_ADDED){
char buf[MAX_PATH]{};
WideCharToMultiByte(CP_ACP, 0, lpInfomation->FileName, -1, buf, MAX_PATH, NULL, NULL);
printf("new file added '%s'", buf);
}
memset(lpBuffer, 0, MAX_PATH*sizeof(wchar_t));
}
ReadDirectoryChangesW(hdir, lpBuffer, MAX_PATH, TRUE, dwNotifyFilter, NULL, &olp, NULL);
}
}
Sleep(10);
}
(2) 他のプロセスがファイル作成を完了する(ハンドルを開放する)まで待つ
# include <RestartManager.h>
# pragma comment(lib, "Rstrtmgr.lib")
int EnumProcessFileOpened(char filenameA[])
{
WCHAR filenameW[MAX_PATH];
MultiByteToWideChar(CP_ACP, 0, filenameA, -1, filenameW, MAX_PATH);
const int nfiles=1;
LPCWSTR pszfiles[nfiles];
pszfiles[0]=filenameW;
int nproc=-1;
DWORD dwError;
DWORD dwSession;
WCHAR szSessionKey[CCH_RM_SESSION_KEY+1]{};
dwError=RmStartSession(&dwSession, 0, szSessionKey);
if(dwError==ERROR_SUCCESS){
dwError=RmRegisterResources(dwSession, nfiles, pszfiles, 0, NULL, 0, NULL);
if(dwError==ERROR_SUCCESS){
UINT nProcInfoNeeded=0;
UINT nProcInfo=0;
RM_PROCESS_INFO *rgpi=NULL;
DWORD dwReason=RmRebootReasonNone;
dwError=RmGetList(dwSession, &nProcInfoNeeded, &nProcInfo, rgpi, &dwReason);
if(dwError==ERROR_MORE_DATA){
printf("this file is opened by %d processes", nProcInfoNeeded);
nproc=nProcInfoNeeded;
}else if(dwError==ERROR_SUCCESS){
printf("this file is opened by %d processes", nProcInfoNeeded);
}else{
nproc=-1;
}
}
RmEndSession(dwSession);
}
return nproc;
}
2. 読み込みに時間かかってるから途中でキャンセル
読み込みスレッド
HANDLE hthread=INVALID_HANDLE_VALUE;
DWORD __stdcall ThreadProc(void *h)
{
HANDLE *hfile=static_cast<HANDLE *>(h);
unsigned char buffer[LARGE_SIZE];
DWORD dwSize;
ReadFile(*hfile, buffer, LARGE_SIZE, &dwSize, 0);
return 0;
}
呼び出し側
HANDLE hfile=CreateFile("c:\\Work\\test.txt", GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
hthread=CreateThread(NULL, 0, ThreadProc, &hfile, 0, NULL);
...
CancelIoEx(hfile, NULL);
WaitForSingleObject(hthread, INFINITE);
CloseFile(hfile);
3. 書き込んだけど全部キャンセル(トランザクションNTFSの利用)
HANDLE htran=CreateTransaction(NULL, 0, TRANSACTION_DO_NOT_PROMOTE, 0, 0, 0, L"");
HANDLE hfile=CreateFileTransacted("c:\\Work\\test1.txt", GENERIC_WRITE, 0, NULL, OPEN_ALWAYS,
FILE_ATTRIBUTE_NORMAL, NULL,
htran, NULL, NULL);
DWORD dwSize;
WriteFile(hfile, "test", 4, &dwSize, NULL);
CloseHandle(hfile);
// CommitTransaction(htran); //Commitする場合には、今までのファイル操作をアトミックに反映
RollbackTransaction(htran);
CloseHandle(htran);