进程ID和窗口间相互获得和转换
2015-04-27 16:35:25 访问(1812) 赞(0) 踩(0)
#pragma once
#define SEM_OBJECT TEXT("C_CHECK_OBJECT")
#define STR_TARGET_PROCNAME TEXT("Mp.exe")
enum {FLAG_CLOSE,FLAG_DATE_RESTART,FLAG_MIN_RESTART,FLAG_BACKUP,FLAG_ERROR_RESTART,FLAG_HANDLE};
class CCheckObject
{
public:
CCheckObject(void);
~CCheckObject(void);
private:
HANDLE m_hEvent;
HWND m_hWnd;
public:
TCHAR m_szPath[MAX_PATH+1];
BOOL IsProcessExist(LPCTSTR strName);//通过进程名,判断进程是否存在
DWORD GetProcessId(LPCTSTR strName);//通过进程名,返回进程ID
DWORD GetThreadId(LPCTSTR strName);//通过进程名,返回主线程ID
DWORD GetThreadId(DWORD dwProcessID);//通过进程ID得到主线程ID
HWND GetTargetWindowHanle(LPCTSTR strName);//通过进程名,得到主窗口句柄.
BOOL IsExeExist(); //判断当前程序是否已经在运行.
BOOL chSetProp(HWND hWnd); //设置程序唯一性标记
BOOL chRemoveProp(); //移除程序唯一性标记
BOOL RunExe(LPCTSTR lpAppPathName,LPTSTR lpCmdLine);//传入exe完整路径,和命令行参数,运行一个外部程序.
};
#include "StdAfx.h"
#include "CheckObject.h"
#include <Tlhelp32.h>//方法1,toolhelp32
#include <Psapi.h> //方法2 ,EnumProcesses
#pragma comment(lib,"psapi.lib")
#include <WtsApi32.h>
#pragma comment(lib,"wtsapi32.lib")//WTSOpenServer WTSEnumProcessInfo
#include <LM.h>
#pragma comment(lib,"netapi32.lib")//NetServerGetInfo 获得NetBios
#include <shlwapi.h>
#pragma comment(lib,"shlwapi.lib") //EnumThreadWindows
CCheckObject::CCheckObject(void)
{
m_hEvent=NULL;
m_hWnd=NULL;
//获得当前工程路径
memset(m_szPath,0,(MAX_PATH+1)*sizeof(TCHAR));
GetModuleFileName(NULL,m_szPath,MAX_PATH);
TCHAR *pChar=_tcsrchr(m_szPath,'\\');
int len=_tcslen(pChar);
memset(pChar,0,len*sizeof(TCHAR));
}
CCheckObject::~CCheckObject(void)
{
chRemoveProp();
CloseHandle(m_hEvent);
}
void PrintProcessNameAndID( DWORD processID )
{
TCHAR szProcessName[MAX_PATH] = TEXT("<unknown>");
// 获得进程句柄
HANDLE hProcess = OpenProcess( PROCESS_QUERY_INFORMATION |
PROCESS_VM_READ,
FALSE, processID );
//获得进程名.
if (NULL != hProcess )
{
HMODULE hMod;
DWORD cbNeeded;
//枚举进程中的模块
if ( EnumProcessModules( hProcess, &hMod, sizeof(hMod),
&cbNeeded) )
{
//得到模块相关信息
GetModuleBaseName( hProcess, hMod, szProcessName, sizeof(szProcessName)/sizeof(TCHAR) );
/*if(0==GetModuleFileName(hMod,szProcessName,sizeof(szProcessName)/sizeof(TCHAR)))
{
TCHAR ebuf[20]={0};
_stprintf(ebuf,TEXT("错误号:%d"),GetLastError());
OutputDebugString(ebuf);
GetModuleBaseName( hProcess, hMod, szProcessName, sizeof(szProcessName)/sizeof(TCHAR) );
}*/
}
}
// 输出进程名和进程ID.
TCHAR buf[MAX_PATH]={0};
_stprintf(buf, TEXT("%s (PID: %u)\n"), szProcessName, processID );
OutputDebugString(buf);//输出到DebugView中.
CloseHandle( hProcess );
}
BOOL CCheckObject::IsProcessExist(LPCTSTR strName)
{
if(strName==NULL)
{
return FALSE;
}
//遍历进程的方法
//方法一,ToolHelp32遍历
HANDLE hProcess=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
BOOL bHave=FALSE;
PROCESSENTRY32 pe32;
pe32.dwSize=sizeof(pe32);
if(hProcess)
{
bHave=Process32First(hProcess,&pe32);
while(bHave)
{
bHave=Process32Next(hProcess,&pe32);
//OutputDebugString(pe32.szExeFile);
if(_tcsicmp(strName,pe32.szExeFile)==0)
{
return TRUE;
}
}
}
//方法二 进程枚举函数EnumProcesses
/*DWORD aProcesses[1024], cbNeeded, cProcesses;
unsigned int i;
if ( !EnumProcesses( aProcesses, sizeof(aProcesses), &cbNeeded ) )
return FALSE;
// Calculate how many process identifiers were returned.
cProcesses = cbNeeded / sizeof(DWORD);
// Print the name and process identifier for each process.
for ( i = 0; i < cProcesses; i++ )
if( aProcesses[i] != 0 )
PrintProcessNameAndID( aProcesses[i] );
*/
//方法三 WTSEnumerateProcesses
//获得远程计算机的NetBios
/*DWORD dwLevel = 101;
LPSERVER_INFO_101 pBuf = NULL;
NET_API_STATUS nStatus;
LPTSTR pszServerName = NULL;//
nStatus = NetServerGetInfo(pszServerName,
dwLevel,
(LPBYTE *)&pBuf);
if (nStatus == NERR_Success)
{
if ((pBuf->sv101_type & SV_TYPE_DOMAIN_CTRL) ||
(pBuf->sv101_type & SV_TYPE_DOMAIN_BAKCTRL) ||
(pBuf->sv101_type & SV_TYPE_SERVER_NT))
OutputDebugString(TEXT("This is a server\n"));
else
OutputDebugString(TEXT("This is a workstation\n"));
}
//打开对应名字服务.
HANDLE hWtsServer = WTSOpenServer(pBuf->sv101_name);
//释放
if (pBuf != NULL)
NetApiBufferFree(pBuf);*/
//以下可完成获得本机的,不需要以上获得的数据.
/*PWTS_PROCESS_INFO pWtspi;
DWORD dwCount=0;
//枚举进程信息.
if(!WTSEnumerateProcesses(WTS_CURRENT_SERVER_HANDLE, //当前机子,HANDLE直接用WTS_CURRENT_SERVER_HANDLE就可以了
0,
1,
&pWtspi,
&dwCount))
{
return FALSE;
};
TCHAR buf[MAX_PATH]={0};
for(int i=0; i<dwCount; i++)
{
memset(buf,0,MAX_PATH*sizeof(TCHAR));
_stprintf(buf,TEXT("ps_Id: %d ps_name: %s "), pWtspi[i].ProcessId, pWtspi[i].pProcessName);
OutputDebugString(buf);
} */
return FALSE;
}
DWORD CCheckObject::GetProcessId(LPCTSTR strName)
{
if(strName==NULL)
{
return 0;
}
HANDLE hProcess=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
BOOL bHave=FALSE;
PROCESSENTRY32 pe32;
pe32.dwSize=sizeof(pe32);
TCHAR buf[100]={0};
if(hProcess)
{
bHave=Process32First(hProcess,&pe32);
while(bHave)
{
bHave=Process32Next(hProcess,&pe32);
//OutputDebugString(pe32.szExeFile);
//memset(buf,0,100*sizeof(TCHAR));
//_stprintf(buf,TEXT("进程ID:%04d 线程数量:%d"),pe32.th32ProcessID,pe32.cntThreads);
//OutputDebugString(buf);
//GetThreadId(pe32.th32ProcessID);
if(_tcsicmp(strName,pe32.szExeFile)==0)
{
//memset(buf,0,100*sizeof(TCHAR));
//_stprintf(buf,TEXT("进程名:%s 进程ID:%04d 线程数量:%d"),pe32.szExeFile,pe32.th32ProcessID,pe32.cntThreads);
//OutputDebugString(buf);
return pe32.th32ProcessID;
}
}
}
return 0;
}
DWORD CCheckObject::GetThreadId(DWORD dwProcessID)
{
if(dwProcessID==0)
{
return 0;
}
HANDLE hThread=CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD,0);
BOOL bHave=FALSE;
THREADENTRY32 pe32;
pe32.dwSize=sizeof(pe32);
TCHAR buf[100]={0};
if(hThread)
{
bHave=Thread32First(hThread,&pe32);
while(bHave)
{
bHave=Thread32Next(hThread,&pe32);
if(pe32.th32OwnerProcessID==dwProcessID)//第一个一般就是主线程ID.
{
//memset(buf,0,100*sizeof(TCHAR));
//_stprintf(buf,TEXT(" 线程ID:%04d"),pe32.th32ThreadID);
//OutputDebugString(buf);
return pe32.th32ThreadID;
}
}
}
return 0;
}
DWORD CCheckObject::GetThreadId(LPCTSTR strName)
{
if(strName==NULL)
{
return 0;
}
return GetThreadId(GetProcessId(strName));
}
BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam )
{
TCHAR buf[100]={0};
GetWindowText(hwnd,buf,100);
OutputDebugString(buf);
if(::GetProp(hwnd,SEM_OBJECT))
{
::ShowWindow(hwnd,SW_RESTORE);
::SetForegroundWindow(hwnd);
return FALSE;
}
return TRUE;
}
BOOL CCheckObject::IsExeExist()
{
//让本程序只远行一个实例
//方法1
HANDLE hEvent = OpenEvent(EVENT_ALL_ACCESS,TRUE,SEM_OBJECT);
if(NULL != hEvent)
{
//TCHAR buf[MAX_PATH]={0};
//GetModuleFileName(NULL,buf,MAX_PATH);
//CCheckObject ch;
//DWORD dwThreadId=ch.GetThreadId(PathFindFileName(buf));
//EnumThreadWindows(dwThreadId,EnumThreadWndProc,NULL);
CloseHandle(hEvent);
//OutputDebugString(TEXT("该程序已经在运行,不能打开另一个副本!"));
return TRUE;
}
m_hEvent = CreateEvent(NULL,TRUE,TRUE,SEM_OBJECT);
//方法2
/*HANDLE hSem=CreateSemaphore(NULL,1,1,SEM_OBJECT);
if(hSem)
{
if(ERROR_ALREADY_EXISTS==GetLastError())//如果是已经存在,则说明程序已经运行过.
{
EnumWindows(EnumWindowsProc,NULL);
return TRUE;
}
}*/
return FALSE;
}
BOOL CCheckObject::chSetProp(HWND hWnd)
{
if(hWnd)
{
if(::SetProp(hWnd,SEM_OBJECT,(HANDLE)112233))
{
m_hWnd=hWnd;
return TRUE;
}
}
return FALSE;
}
BOOL CCheckObject::chRemoveProp()
{
if(m_hWnd)
{
::RemoveProp(m_hWnd,SEM_OBJECT);
return TRUE;
}
return FALSE;
}
//加强枚举;
BOOL CALLBACK EnhanceEnumProcWnd(HWND hWnd,LPARAM lParam)
{
DWORD ProcID=0;
DWORD pId=*(PDWORD)lParam;
DWORD dwThreadId=GetWindowThreadProcessId(hWnd,&ProcID);
if(dwThreadId==pId)
{
DWORD Style=GetWindowLong(hWnd,GWL_STYLE);
if( !(Style&WS_CHILDWINDOW) && GetParent(hWnd)==NULL && GetWindow(hWnd,GW_CHILD)!=NULL)//非子 无父 并且 有子
{
/*OutputDebugString(TEXT("find wnd"));
*(PDWORD)lParam=(DWORD)hwnd;
return FALSE;*/
/*CString Str;
Str.Format(TEXT("%08X--%X"),hWnd,Style);
Str+=TEXT(" -------MainWnd-----");
TCHAR buf[0x30]={0};
GetClassName(hWnd,buf,0x30);
Str+=buf;
OutputDebugString(Str);*/
*(PDWORD)lParam=(DWORD)hWnd;
return FALSE;
}
}
return TRUE;
}
//
BOOL CALLBACK EnumProcHwnd(HWND hwnd, LPARAM lParam )
{
DWORD ProcID=0;
DWORD pId=*(PDWORD)lParam;
DWORD dwThreadId=GetWindowThreadProcessId(hwnd,&ProcID);
if(dwThreadId==pId)
{
DWORD Style=GetWindowLong(hwnd,GWL_STYLE);
if( !(Style&WS_CHILDWINDOW) && GetParent(hwnd)==NULL )//非子窗口 并且 无父窗口
{
/*OutputDebugString(TEXT("find wnd"));
*(PDWORD)lParam=(DWORD)hwnd;
return FALSE;*/
/*CString Str;
Str.Format(TEXT("%08X--%X"),hwnd,Style);
Str+=TEXT(" -------MainWnd-----");
TCHAR buf[0x30]={0};
GetClassName(hwnd,buf,0x30);
Str+=buf;
OutputDebugString(Str);*/
*(PDWORD)lParam=(DWORD)hwnd;
return FALSE;
}
}
return TRUE;
}
//加强枚举.
BOOL CALLBACK EnEnumThreadWndProc(HWND hwnd,LPARAM lParam)
{
if(GetParent(hwnd)==NULL && GetWindow(hwnd,GW_CHILD)!=NULL)//无父窗口 并且 有子窗口
{
*(PDWORD)lParam=(DWORD)hwnd;
return FALSE;
}
return TRUE;
}
BOOL CALLBACK EnumThreadWndProc(HWND hwnd,LPARAM lParam)
{
if(GetParent(hwnd)==NULL)//无父窗口
{
*(PDWORD)lParam=(DWORD)hwnd;//返回找到的窗口句柄
return FALSE;
}
return TRUE;
}
HWND CCheckObject::GetTargetWindowHanle(LPCTSTR strName)
{
DWORD ProcId=GetThreadId(strName);
DWORD Handle=ProcId;
//方法1
/*EnumWindows(EnhanceEnumProcWnd,(LPARAM)&Handle);
if(Handle==ProcId)//如果加强枚举没有得到,则降低条件
{
EnumWindows(EnumProcHwnd,(LPARAM)&Handle);
}*/
//方法2;
EnumThreadWindows(ProcId,EnEnumThreadWndProc,(LPARAM)&Handle);
if(Handle==ProcId)
{
EnumThreadWindows(ProcId,EnumWindowsProc,(LPARAM)&Handle);
}
//MoveWindow(HWND(*ProcId),0,0,100,100);
return Handle==ProcId?NULL:(HWND)Handle;
}
BOOL CCheckObject::RunExe(LPCTSTR lpAppPathName,LPTSTR lpCmdLine)
{
STARTUPINFO si;
memset(&si,0,sizeof(STARTUPINFO));
si.cb=sizeof(STARTUPINFO);//这一步一定要有.不然程序不能运行.
PROCESS_INFORMATION pi;
if(CreateProcess(lpAppPathName,lpCmdLine,NULL,NULL,FALSE,CREATE_SUSPENDED,NULL,NULL,&si,&pi))
{
::ResumeThread(pi.hThread);
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
return TRUE;
}
return FALSE;
}
标签:
进程ID和窗口间相互获得和转换 


上一条:
下一条:
相关评论
发表评论