监听指定进程并获取其用户名
今天的这个内容,主要是为了补上次的坑,坑在这里通过判定当前登录系统用户,启动不同的应用程序,简单描述一下就是我会启动两个账户,启动两个程序,监听程序没有判断启动的程序属于那个用户,所以只有有一个启动,监听程序就会运行指定功能,这就导致我在第二个用户中,关闭了程序,监听程序还是会运行,这坑差点害死我,让测试小姐姐锤了一顿,不过今天没有梦到张扁扁。
这个小程序就是从哪个监听程序的代码中摘一部分,做功能验证,就是获取指定进程的用户名,不过还是不理想,只能获取到部分进程的用户名,像系统级别的进程还是获取不到,即使我以管理员权限运行了,也是不可以。但是我抄人家代码,看人家演示程序是没有问题的,也不知道问题出在哪里了,不过好在可以解决当下文档,先用此坑填前坑,完了再想办法填此坑。
关键字: CreateToolhelp32Snapshot
、GetTokenInformation
、LookupAccountSidW
、管理员权限
、QMAKE_LFLAGS
1获取特定进程
这部分代码在前面的通过判定当前登录系统用户,启动不同的应用程序
文章中有,在复制一下,保证下文章的完整性质。
bool Widget::listenProcess(QString processName)
{
bool isRuning = false;
HANDLE processHandle = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0); //拍摄系统当前所有进程快照
if((HANDLE)-1 == processHandle)
{
return false;
}
PROCESSENTRY32 pInfo; //进程信息
pInfo.dwSize = sizeof (PROCESSENTRY32);
bool bResult = Process32First(processHandle,&pInfo); //获得第一个进程,进程快照迭代器
if(!bResult)
{
return false;
}
QString currentProcessName = "";
while (bResult) {
currentProcessName = QString("%1").arg(QString::fromUtf16(reinterpret_cast<const unsigned short *>(pInfo.szExeFile)));
if(currentProcessName == processName)
{
qDebug() << "用户名:"<< getProcessOwner(pInfo.th32ProcessID);
ui->textEdit_show->append("用户名:" + QString::fromLatin1(getProcessOwner(pInfo.th32ProcessID)));
isRuning = true;
break;
}
bResult = Process32Next(processHandle,&pInfo);
}
return isRuning;
}
2 通过PID获取进程用户名
这个是新增的,也是抄来的,不过原始网址是一个国外的,今天没有找到,作者看到告诉我一下。
char * Widget::getProcessOwner(DWORD pid)
{
char* owner = new char[513];
*owner = '\0';
qDebug() << "PID:" << pid;
HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION,FALSE,pid);
if(hProcess == NULL)
{
return owner;
}
HANDLE hToken = NULL;
DWORD dwSize = 0;
TCHAR szUserName[256] = {0};
TCHAR szDomain[256] = {0};
DWORD dwDomainSize = 256;
DWORD dwNameSize = 256;
SID_NAME_USE SNU;
PTOKEN_USER pTokenUser = NULL;
if(!OpenProcessToken(hProcess,TOKEN_QUERY,&hToken))
qDebug() << "123";
qDebug() << hToken;
if(!GetTokenInformation(hToken,TokenUser,pTokenUser,dwSize,&dwSize))
{
if(GetLastError() != ERROR_HV_INSUFFICIENT_BUFFER)
qDebug() << GetLastError();
}
pTokenUser = NULL;
pTokenUser = (PTOKEN_USER)malloc(dwSize);
if(pTokenUser == NULL)
qDebug() << "345";
if(!GetTokenInformation(hToken,TokenUser,pTokenUser,dwSize,&dwSize))
qDebug() << "456";
if(LookupAccountSidW(NULL,pTokenUser->User.Sid,szUserName,&dwNameSize,szDomain,&dwDomainSize,&SNU) != 0)
sprintf(owner,"%s\0",toChar(szUserName));
if(pTokenUser != NULL)
free(pTokenUser);
return owner;
}
3 宽字符转Char*
这个就是标准的代码了,直接抄
char *Widget::toChar(const wchar_t *_wchar)
{
int len = WideCharToMultiByte(CP_ACP,0,_wchar,-1,NULL,0,NULL,NULL);
char* _char = new char[len];
WideCharToMultiByte(CP_ACP,0,_wchar,-1,_char,len,NULL,NULL);
return _char;
}
4 获取管理员权限
其实完成上面的代码,是可以获取到部分由用户创建的进程的用户名的,但是像系统创建的是没有,通过使用管理员权限,还是不可以,目前还没有搞到问题点,提升管理权限也没有啥大用途,烦人。提升管理员权限代码如下:
直接放在pro中QMAKE_LFLAGS += /MANIFESTUAC:\"level=\'requireAdministrator\' uiAccess=\'false\'\"
5演示下效果
成功的
不成功的
☞ 源码
源码链接:GitHub仓库自取
使用方法:☟☟☟