QtApplets-监听指定进程并获得其用户名

234 阅读3分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。 头图

监听指定进程并获取其用户名

今天的这个内容,主要是为了补上次的坑,坑在这里通过判定当前登录系统用户,启动不同的应用程序,简单描述一下就是我会启动两个账户,启动两个程序,监听程序没有判断启动的程序属于那个用户,所以只有有一个启动,监听程序就会运行指定功能,这就导致我在第二个用户中,关闭了程序,监听程序还是会运行,这坑差点害死我,让测试小姐姐锤了一顿,不过今天没有梦到张扁扁

这个小程序就是从哪个监听程序的代码中摘一部分,做功能验证,就是获取指定进程的用户名,不过还是不理想,只能获取到部分进程的用户名,像系统级别的进程还是获取不到,即使我以管理员权限运行了,也是不可以。但是我抄人家代码,看人家演示程序是没有问题的,也不知道问题出在哪里了,不过好在可以解决当下文档,先用此坑填前坑,完了再想办法填此坑。


监听指定进程并获取其用户名1获取特定进程2 通过PID获取进程用户名3 宽字符转Char*4 获取管理员权限5演示下效果☞ 源码

关键字: CreateToolhelp32SnapshotGetTokenInformationLookupAccountSidW管理员权限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演示下效果

成功的

gif5

不成功的

gif6

☞ 源码

源码链接:GitHub仓库自取

使用方法:☟☟☟


博客签名2021