获取所有的CAD的进程号,窗口句柄,类名,窗口标题
#include "stdafx.h"#include "TlHelp32.h"
#include "GetProcess.h"
#include "Psapi.h"
#include "winver.h"
#include "MSCorEE.h"
CString strWindows = _T("");
#pragma comment(lib, "version.lib")
#pragma comment(lib, "Psapi.lib")
#pragma comment(lib, "mscoree.lib")
struct LANGANDCODEPAGE
{
WORD wLanguage;
WORD wCodePage;
} *lpTranslate;
//----------------------------------------------------------------------------------
//另外方法
//枚举回调函数
BOOL CALLBACK EnumWindowsProc(HWND hWnd,LPARAM lParam)
{
DWORD dwProcessId(0);
LPWNDINFO pInfo = (LPWNDINFO)lParam;
//通过窗口句柄获取进程ID
GetWindowThreadProcessId(hWnd, &dwProcessId);
TCHAR szText;
::GetWindowText(hWnd,szText,MAX_PATH);
//匹配遍历窗口进程号与通过进程名得到的进程号
TRACE( _T("EnumWindowsProc..hWnd=0x%x, ProcessID=%d, WindowsText=%s \n"), hWnd, dwProcessId, szText );
if(dwProcessId == pInfo->dwProcessId && IsWindowVisible(hWnd))
{
TCHAR szClassName;
GetClassName(hWnd,szClassName,80);
HWND hParent = (HWND)::GetWindowLong(hWnd,-8); //GWL_HWNDPARENT ;_WIN64,GWLP_HWNDPARENT
if (hParent == 0 && _tcsncmp(szClassName,_T("Afx"),3) == 0 )
{
strWindows +=_T("\n");
strWindows += szText;
//CString strTemp;
//strTemp.Format(_T("窗口句柄:%ld,父窗口句柄:%ld,窗口文本%s,窗口类别:%s"),hWnd,hParent,szText,szClassName);
//AfxMessageBox(strTemp);
pInfo->hWnd = hWnd;
pInfo->strClassName = szClassName;
pInfo->strWindowText = szText;
return FALSE;
}
}
return TRUE;
}
//获取所有的CAD的进程号,窗口句柄,类名,窗口标题,
int GFindWindows(LPCTSTR proc_name,vector<WNDINFO>&WndSet)
{
int num=0;//返回的窗口句柄数目
WndSet.clear();
DWORD dwPID = 0;//一个临时PID
int a;//存放进程PID的数组
DWORD Proc_num=0;//进程数量
CString procname(proc_name);
//匹配进程名是否含 exe
if (_tcscmp(procname.Right(procname.GetLength() - procname.ReverseFind('.') - 1),_T("exe")))
{
return -1;//参数错误返回-1
}
//************************根据进程名称获取进程ID***********//
HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (INVALID_HANDLE_VALUE == hSnapshot)
{
return 0;
}
PROCESSENTRY32 pe = { sizeof(pe) };
BOOL fOk;
for (fOk = Process32First(hSnapshot, &pe); fOk; fOk = Process32Next(hSnapshot, &pe))
{
CString temp;
TRACE(_T("当前查找进程的名称是: %s\n"),pe.szExeFile);
TRACE(_T("当前进程PID: %d \n"),pe.th32ProcessID);
if (!_tcscmp(pe.szExeFile, proc_name))
{
//CloseHandle(hSnapshot);
temp.Format(_T("当前进程PID: %d \n"),pe.th32ProcessID);
TRACE(_T("当前匹配的进程PID: %d \n"),pe.th32ProcessID);
a = pe.th32ProcessID;
Proc_num++;
}
}
//进程数量为0 提示找不到进程 返回为0;
if (Proc_num==0)
{
return 0;
}
else//找到一个匹配进程
{
strWindows.Empty();
WNDINFO wi;
//对一个进程名有多个相同进程ID的全部数组进行处理
for (DWORD j=0;j<Proc_num;j++)
{
wi.hWnd = NULL;
wi.dwProcessId =a;//将获取到的进程ID传给结构体
wi.strAppPath = GetProcessPath(a);
wi.strVersion = GetAppVersion(wi.strAppPath);
//遍历顶层窗口获取窗口句柄
EnumWindows(EnumWindowsProc,(LPARAM)&wi);
//判断当前进程是否无窗口 无窗口句柄则不保存
if (wi.hWnd!=NULL)
{
WndSet.push_back(wi); //如果是需要的进程,则加入!!!!!!
}
}
//AfxMessageBox(strWindows);
return num;//返回句柄个数
}
}
//获取文件版本号
CString GetAppVersion(LPCTSTR pcszFileName)
{
if (_tcscmp(pcszFileName,_T("X64")) == 0)
{
return pcszFileName;
}
//上面的小段为我加
DWORD dwSize = 0;
DWORD uiSize = GetFileVersionInfoSize(pcszFileName,&dwSize);
if (0 == uiSize)
{
//0 意味着GetFileVersionInfoSize 函数调用失败
return _T("");
}
PTSTR pBuffer = new TCHAR;
if (NULL == pBuffer)
{
//分配内存失败:)
return _T("");
}
memset((void*)pBuffer,0,uiSize);
//获取exe 或 DLL 的资源信息,存放在pBuffer内
if(!GetFileVersionInfo(pcszFileName,0,uiSize,(PVOID)pBuffer))
{
//GetFileVersionInfo 调用失败.
delete []pBuffer;
return _T("");
}
LANGANDCODEPAGE *pLanguage = NULL;//这里这样设置没关系了。
UINTuiOtherSize = 0;
//获取资源相关的 codepage 和language
if (!VerQueryValue(pBuffer,_T("\\VarFileInfo\\Translation"),
(PVOID*)&pLanguage,&uiOtherSize))
{
//出错
delete []pBuffer;
return _T("");
}
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
//超级重点
LPVOID pTmp = NULL; //一定要把pTmp这个变量设置成PVOID或LPVOID型的
//否则无法获取信息。你不信可以试。
//TCHAR *pTmp = NULL;
//或下面这样的设置
//TCHAR pTmp;
//memset((void*)pTmp,0,sizeof(pTmp));
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
TCHAR SubBlock;
memset((void*)SubBlock,0,sizeof(SubBlock));
CString strVersion;
for(UINT i=0; i < (uiOtherSize / sizeof(LANGANDCODEPAGE)); i++ )
{
//获取每种 CodePage 和 Language 资源的相关信息
wsprintf(SubBlock,
TEXT("\\StringFileInfo\\%04x%04x\\FileVersion"),
pLanguage.wLanguage,
pLanguage.wCodePage);
// Comments InternalName ProductName
// CompanyName LegalCopyright ProductVersion
// FileDescription LegalTrademarks PrivateBuild
// FileVersion OriginalFilename SpecialBuild
// OriginalFilename 可由上面的各种代替。
// Retrieve file description for language and code page "i".
int nRet = VerQueryValue(pBuffer,SubBlock, (LPVOID*)&pTmp, &uiOtherSize);
if (nRet != 0)
{
strVersion.Format(_T("%s"),(TCHAR*)pTmp);
}
}
delete []pBuffer;
pBuffer = NULL;
return strVersion;
}
//获取进程路径
CString GetProcessPath( DWORD idProcess )
{
// 获取进程路径
TCHAR szProcessName = _T("");
// 打开进程句柄,需要管理员权限
HANDLE hProcess = OpenProcess( PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, idProcess );
if( NULL != hProcess )
{
HMODULE hMod;
DWORD cbNeeded;
// 获取路径
if( EnumProcessModules( hProcess, &hMod, (DWORD)sizeof( hMod ), (LPDWORD)&cbNeeded ) )
{
DWORD dw = GetModuleFileNameEx( hProcess, hMod, szProcessName, MAX_PATH );
}
else
{
//此处最可能碰到299错误,即如果编译成32位程序,去调用64位CAD
TRACE(_T("出错代码是:%d"),GetLastError());
int nError = GetLastError();//WSAGetLastError
if (nError == 299)
{
CloseHandle(hProcess);
return _T("X64"); //64位的CAD
}
}
CloseHandle( hProcess );
}
return (szProcessName);
}
//将wchar_t* 转成char*的实现函数如下:
char *w2c(const wchar_t *pwstr)
{
//size_t nlength=wcslen(pwstr);
//获取转换后的长度
size_t nbytes = WideCharToMultiByte( 0, // specify the code page used to perform the conversion
0, // no special flags to handle unmapped characters
pwstr, // wide character string to convert
-1,//nlength, // the number of wide characters in that string
NULL, // no output buffer given, we just want to know how long it needs to be
0,
NULL, // no replacement character given
NULL ); // we don't want to know if a character didn't make it through the translation
// make sure the buffer is big enough for this, making it larger if necessary
//if( nbytes > len)
//nbytes=len;
char *pcstr = new char;
// 通过以上得到的结果,转换unicode 字符为ascii 字符
WideCharToMultiByte( 0, // specify the code page used to perform the conversion
0, // no special flags to handle unmapped characters
pwstr, // wide character string to convert
-1,//nlength, // the number of wide characters in that string
pcstr, // put the output ascii characters at the end of the buffer
nbytes, // there is at least this much space there
NULL, // no replacement character given
NULL );
return pcstr ;
}
//把ascii 字符转换为unicode字符
wchar_t* c2w(wchar_t *pwstr, const char *str)
{
wchar_t* buffer=NULL;
if(str != NULL)
{
size_t nu = strlen(str);
size_t n =(size_t)MultiByteToWideChar(CP_ACP,0,(const char *)str,int(nu),NULL,0);
buffer = new wchar_t;
::MultiByteToWideChar(CP_ACP,0,(const char *)str,int(nu),buffer,int(n));
}
return buffer;
}
页:
[1]