在程序中经常需要删除某一个指定文件,但有些文件一直会被资源管理器占用,所以总是删除失败.如果要强行用程序删除除了360那种暴力删除还有一种比较容易想到的就是结束资源管理器并删除文件,然后在把资源管理器起来.
哈,总算引到这上面来了.
结束进程,经常使用TerminateProcess函数,创建进程使用CreateProcess.
但就是这两个常见的函数也有一些鲜为人知的”秘密”(姑且这样叫).
首先讨论TerminateProcess:
BOOL WINAPI TerminateProcess(
__in HANDLE hProcess,
__in UINT uExitCode //进程退出码
);
需要注意的几点:
■ TerminateProcess函数是异步的.这表明使用它之后需要WaitForSingleObject.
■ 如果想知道进程退出码,可以查看uExitCode的返回值,但是如果想结束Explorer.exe进程时不传1,Explorer.exe就无法结束(结束后马上会调起来).这个是很奇怪的现象,毕竟很少地方会提及这一点.
然后是CreateProcess这个函数:
BOOL WINAPI CreateProcess(
__in LPCTSTR lpApplicationName,
__in_out LPTSTR lpCommandLine,
__in LPSECURITY_ATTRIBUTES lpProcessAttributes,
__in LPSECURITY_ATTRIBUTES lpThreadAttributes,
__in BOOL bInheritHandles,
__in DWORD dwCreationFlags,
__in LPVOID lpEnvironment,
__in LPCTSTR lpCurrentDirectory,
__in LPSTARTUPINFO lpStartupInfo,//结构必须清零
__out LPPROCESS_INFORMATION lpProcessInformation
);
需要注意的几点:
■ lpStartupInfo结构如果在传递前不清零,那么CreateProcess可能会不成功.
■ 进程创建后记得CloseHandle创建进程和其主线程句柄.否则将引起内存泄漏.
■ 对Explorer.exe而言,如果只是简单的将其赋值给lpCommandLine,那么xp没有问题,win7旗舰版(32bit)就会出现资源管理器异常(可以打开我的电脑查看),win7旗舰版(64bit)就无法调起来,它打开的是我的文档.CreateProcess本来可以按照特定目录去查找进程的路径(先主进程所在目录,然后当前目录,然后系统目录....),为什么它会”找不到”?(也不能这样讲,毕竟系统已经为我们启动了一个类Explorer.exe进程.
至于win7家庭版有什么现象我暂时不得而知,因为手上没有家庭版win7系统.
上图是win7(32bit)旗舰版出现的情况.
贴代码:
HANDLE hSnapshot = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS,0 ); TCHAR chProcessName[MAX_PATH] = TEXT("EXPLORER.EXE"); PROCESSENTRY32 proceList; proceList.dwSize = sizeof( PROCESSENTRY32 ); BOOL ret_Value = Process32First( hSnapshot,&proceList ); while ( ret_Value ) { if ( _tcsicmp( chProcessName,proceList.szExeFile ) == 0 )//_tcsicmp { break; } ret_Value = Process32Next( hSnapshot,&proceList ); } HANDLE hProcess = OpenProcess( PROCESS_ALL_ACCESS,FALSE,proceList.th32ProcessID ); TerminateProcess( hProcess,1 ); WaitForSingleObject( hProcess,INFINITE ); CloseHandle(hProcess); CloseHandle(hSnapshot); STARTUPINFO stup = {0}; stup.cb = sizeof( STARTUPINFO ); PROCESS_INFORMATION proInfo; TCHAR chProcessPath[MAX_PATH] = {0}; //1. GetSystemDirectory( chProcessPath,MAX_PATH ); //2. GetWindowsDirectory( chProcessPath,MAX_PATH ); _tcscat( chProcessPath,TEXT("\\") ); _tcscat( chProcessPath,chProcessName ); //3. CreateProcess( NULL,chProcessPath,NULL,NULL,FALSE,0,NULL,NULL,&stup,&proInfo ); //4. CreateProcess( NULL,chProcessName,NULL,NULL,FALSE,0,NULL,NULL,&stup,&proInfo ); DWORD dwErrorCode = GetLastError(); CloseHandle( proInfo.hThread ); CloseHandle( proInfo.hProcess );
大家需要注意我注释的几行.仔细体会这几行的意义.