• 开发一个简易的任务监控程序



    需求:时刻监控任务列表,如果需要一直启动的程序未开启,则开启

    实现:

    1、枚举当前已经启动的进程、获取进程的ID和名称

    	vector
      
        launchedProcess;
    	HANDLE handle=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);//创建当前快照列表
    	PROCESSENTRY32* info=new PROCESSENTRY32;//创建进程信息变量,用于保存信息
    	info->dwSize=sizeof(PROCESSENTRY32);//设置块大小
    	int i=0;
    	if(Process32First(handle,info))//开始枚举进程
    	{
    		if(GetLastError()==ERROR_NO_MORE_FILES )
    		{
    			AfxMessageBox(_T("No More Process"));
    		}
    		else
    		{
    			CString id,file;
    			id.Format(L"%d",info->th32ProcessID);//获取当前进程ID
    			file.Format(L"%s",info->szExeFile);//获取当前进程名
    
    			////TRACE(L"ID:%s,Name:%s",id,file);
    
    			launchedProcess.push_back(file);
    
    			if(!isExistInList(id,file))
    			{
    				m_list.InsertItem(i,id);//插入一个项目
    				m_list.SetItemData(i,info->th32ProcessID);//设置项目值
    				m_list.SetItemText(i,1,file);//设置名
    				i++;
    			}
    			while(Process32Next(handle,info)!=FALSE)//继续获取进程
    			{
    				id.Format(L"%5d",info->th32ProcessID);
    				file.Format(L"%s",info->szExeFile);
    
    				launchedProcess.push_back(file);
    
    				if(!isExistInList(id,file))
    				{
    					m_list.InsertItem(i,id);
    					m_list.SetItemData(i,info->th32ProcessID);
    					m_list.SetItemText(i,1,file);
    					i++;
    				}
    			}
    		}
    	}
    	delete info;//参考博文中未添加
    	CloseHandle(handle);//关闭进程句柄
      

    2、通过进程ID获取进程所对应的执行文件路径,需要实现逻辑设备名映射盘符的问题

    HANDLE hProcess = NULL;  
    	BOOL bSuccess = FALSE;  
    	
    	// 由于进程权限问题,有些进程是无法被OpenProcess的,如果将调用进程的权限  
    	// 提到“调试”权限,则可能可以打开更多的进程  
    	hProcess = OpenProcess(   
    		PROCESS_QUERY_INFORMATION | PROCESS_VM_READ ,   
    		FALSE, dwProcessId );  
    
    	CString path(_T(""));
    	do   
    	{  
    		if ( NULL == hProcess )  
    		{  
    			// 打开句柄失败,比如进程为0的进程  
    			break;  
    		}  
    		
    		// 用于保存文件路径,扩大一位,是为了保证不会有溢出  
    		TCHAR szPath[_MAX_PATH + 1] = {0};  
    		
    		// 模块句柄  
    		HMODULE hMod = NULL;  
    		// 这个参数在这个函数中没用处,仅仅为了调用EnumProcessModules  
    		DWORD cbNeeded = 0;  
    		
    #if 0		
    		// 【注】此种方法Win7-64bit cmd.exe获取不到路径(同时勾选dbgview、chrome、beyondcompare、cmd)
    		
    		// 获取路径  
    		// 因为这个函数只是要获得进程的Exe路径,因为Exe路径正好在返回的数据的  
    		// 第一位,则不用去关心cbNeeded,hMod里即是Exe文件的句柄.  
    		// If this function is called from a 32-bit application running on WOW64,   
    		// it can only enumerate the modules of a 32-bit process.   
    		// If the process is a 64-bit process,   
    		// this function fails and the last error code is ERROR_PARTIAL_COPY (299).  
    		if( FALSE == EnumProcessModules( hProcess, &hMod,   
    			sizeof( hMod ), &cbNeeded ) )  
    		{  
    			break;
    		}  
    		
    		// 通过模块句柄,获取模块所在的文件路径,此处即为进程路径。  
    		// 传的Size为_MAX_PATH,而不是_MAX_PATH+1,是因为保证不会存在溢出问题  
    		if ( 0 == GetModuleFileNameEx( hProcess, hMod, szPath, _MAX_PATH ) )  
    		{  
    			break;  
    		}  
    #endif
    
    #if 1
    		TCHAR szWinPath[_MAX_PATH + 1] = {0};
    
    		//http://www.codeproject.com/Questions/282205/Get-Path-all-of-opened-Windows-WinAPI
    		HINSTANCE hinstLib; 
    		typedef DWORD (WINAPI *FPGetProcessImageFileName)(HANDLE,LPTSTR,DWORD); 
    		FPGetProcessImageFileName fpGetProcessImageFileName = NULL; 
    		
    		// Get a handle to the DLL module.
    		GetWindowsDirectory(szWinPath,sizeof(szWinPath));
    		path.Format(L"%s\SYSTEM32\psapi.dll",szWinPath);
    		
    		////TRACE(L"path:%s",(LPCTSTR)path);
    
    		hinstLib = ::LoadLibrary((LPCTSTR)path); 
    		if (hinstLib != NULL) 
    		{
    #ifdef UNICODE
    #define GetProcessImageFileNameStr  "GetProcessImageFileNameW"
    #else
    #define GetProcessImageFileNameStr  "GetProcessImageFileNameA"
    #endif // !UNICODE
    
    			//http://blog.163.com/danshiming@126/blog/static/109412748201141425648762/
    			CString strFunName = _T(GetProcessImageFileNameStr);
    			CStringA strFunNameA(strFunName);
    			fpGetProcessImageFileName = (FPGetProcessImageFileName) ::GetProcAddress(hinstLib, strFunNameA); 
    			
    			// If the function address is valid, call the function.
    			if (NULL != fpGetProcessImageFileName) 
    			{
    				//
    				if(!fpGetProcessImageFileName(hProcess, szPath, _MAX_PATH))
    					GetLastError();
    			}
    		}
    		else
    		{
    			AfxMessageBox(_T("psapi.dll not found"));
    		}
    		// Free the DLL when you are done.
    		::FreeLibrary(hinstLib);
    #endif
    
    #if 0
    		if(!GetProcessImageFileName(hProcess, szPath, _MAX_PATH))  
    		{  
    			break;  
    		}
    #endif
    		// 保存文件路径  
    		path = szPath;
    		// //TRACE(L"%s",(LPCTSTR)path);
    		// 查找成功了  
    
    #if 1
    		CString deviceName(_T(""));
    		int num=0;//第三次出现的位置左边即为逻辑设备名
    		//"DeviceHarddiskVolume2WindowsSystem32cmd.exe"
    		for(int i=0;i<path.GetLength();i++)
    		{
    			if(path.GetAt(i)=='\')
    			{
    				num++;
    				if(num == 3)
    				{
    					deviceName.Empty();
    					deviceName = path.Left(i);
    					path = path.Right(path.GetLength()-i-1);
    
    					////TRACE(L"logicVolume:%s,path:%s",logicVolume,path);
    					break;
    				}
    			}
    		}
    
    		//TRACE(L"deviceName---%s",deviceName);
    
    		std::map<CString, CString>::iterator iterator1;
    		std::map<CString, CString>::iterator Enditerator1 = m_mapDevicePath.end();
    		for(iterator1 = m_mapDevicePath.begin();iterator1 != Enditerator1; iterator1++)
    		{
    			//TRACE(L"iterator---%s",iterator1->first);
    			CStringA left(iterator1->first);
    			CStringA right(deviceName);
    			//TRACE(L"left---%s",left);
    			//TRACE(L"right---%s",right);
    			if(!left.Compare(right))
    			{
    				//TRACE("helloworld");
    			}
    			if(!iterator1->first.Compare(deviceName))
    			{
    				//TRACE(L"iterator===%s",iterator1->first);
    				//TRACE(L"m_mapDevicePath---%s",m_mapDevicePath[deviceName]);
    				deviceName = iterator1->second;
    				break;
    			}
    		}
    		//TRACE(L"deviceName---%s",deviceName);
    		path = deviceName + path;
    		TRACE(L"path---%s",path);
    		cstrPath = path;
    		path.Empty();
    #endif
    /******
            //两种由逻辑设备名映射盘符的解决链接
    
    		//http://bbs.csdn.net/topics/330144410
    		//IoVolumeDeviceToDosName()//需要ddk驱动神马的,超级麻烦,驱动用的
    
    		//vc6.0不支持,被迫迁移到vs8,一下超链接部分的代码可直接拷贝编译运行
    		//http://msdn.microsoft.com/en-us/library/cc542456(v=VS.85).aspx
    ******/
    		if(cstrPath.GetLength())
    			bSuccess = TRUE;  
    	} while( 0 );
    	
    	// 释放句柄  
    	if ( NULL != hProcess )  
    	{  
    		CloseHandle( hProcess );  
    		hProcess = NULL;  
    	}  
    	

    3、开启进程

    //http://blog.csdn.net/itjobtxq/article/details/6233455
    			SHELLEXECUTEINFO ShExecInfo = {0};
    			ShExecInfo.cbSize = sizeof(SHELLEXECUTEINFO);
    			ShExecInfo.fMask = SEE_MASK_NOCLOSEPROCESS;
    			ShExecInfo.hwnd = NULL;
    			ShExecInfo.lpVerb = NULL;
    			ShExecInfo.lpFile = m_daemonModulePath[i];
    			ShExecInfo.lpParameters =_T("");
    			ShExecInfo.lpDirectory = NULL;
    			ShExecInfo.nShow = SW_SHOW;
    			ShExecInfo.hInstApp = NULL;
    			ShellExecuteEx(&ShExecInfo);
    			WaitForSingleObject(ShExecInfo.hProcess,100);
    
    			launchedProcess.push_back(m_daemonModulePath[i]);

    4、边边角角的需求:只启用一个实例;最小化时任务栏不显示,只在后台中运行;再点击exe的图标,激活后台进程显示主窗口

    其中需求4的最后一个小需求在vs2008生成的执行文件里会失败

    最终程序截图:

    vc6.0                                                                                                              vs2008


    工程和可执行文件下载:http://download.csdn.net/detail/lonelyrains/5705883

  • 相关阅读:
    (转)机器学习——深度学习(Deep Learning)
    (转)Deep Learning深度学习相关入门文章汇摘
    (转)Haar-like矩形遍历检测窗口演示Matlab源代码
    HTML5远程工具
    splinter操作ie浏览器
    Wechat login authorization(OAuth2.0)
    Message Queuing(MSMQ)
    Visual Studio2017 数据库架构比较
    Visual Studio2017 Remote Debugger
    搭建Spring Initializr服务器
  • 原文地址:https://www.cnblogs.com/snake-hand/p/3174660.html
Copyright © 2020-2023  润新知