【Qt】获取当前系统进程并展示(带Icon,同附带扩展名Icon测试 #附效果图#)
1. Qt 获取当前系统进程并展示(附效果图) 纯代码,无GUI2. 获取打开扩展名Icon3. QListWidget应用实例
·
效果图
运行和编译环境
- Win 10
- Qt 5.9 MSVC2017 64位
- gitee源码👈 clone后可直接编译
git clone https://gitee.com/fole-del/qt_-process-with-icon_show.git
Qt 获取当前系统进程并展示
实现手段
- 调用Win API先获取系统当前的进程名和PID
- 根据进程
PID
(PROCESSENTRY32W.th32ProcessID
)获取进程全路径,全路径接口为GetModuleFileNameEx
Icon
:获取Icon并显示,根据第二步获取的全路径,依旧是调用系统API,获取Icon
,得到HICON句柄,使用Qt的QtWin::fromHICON
接收即可获取QIcon
。
获取Icon函数
HICON QueryExeIcon(LPCTSTR lpszExePath)
{
HICON hIcon = NULL;
SHFILEINFO FileInfo;
DWORD_PTR dwRet = ::SHGetFileInfo(lpszExePath, 0, &FileInfo, sizeof(SHFILEINFO), SHGFI_ICON);
// 目标文件不存在
if (dwRet)
{
hIcon = FileInfo.hIcon;
}
return hIcon;
}
获取进程相关函数
int Widget::getAllProcess()
{
int countProcess = 0; //当前进程数量计数变量
HANDLE hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); // 创建进程快照
PROCESSENTRY32W currentProcess; // 用来接收 hProcessSnap 的信息
currentProcess.dwSize = sizeof(currentProcess); //在使用这个结构之前,先设置它的大小
HANDLE hProcess = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);//给系统内的所有进程拍一个快照
if (hProcess == INVALID_HANDLE_VALUE)
{
printf("CreateToolhelp32Snapshot()调用失败!\n");
return -1;
}
bool bMore = Process32First(hProcessSnap, ¤tProcess); //获取第一个进程信息
while (bMore) {
QString str;
TCHAR szProcessName[MAX_PATH] = { 0 };
GetProcessFullPath(currentProcess.th32ProcessID, szProcessName, str); // 该函数后文有完整源码
m_ProList.append(str);
bMore = Process32Next(hProcessSnap, ¤tProcess); //遍历下一个
countProcess++;
}
CloseHandle(hProcess); //清除hProcess句柄
// QMessageBox::information(this,QString::fromLocal8Bit("检测完毕"),QString::fromLocal8Bit("共有以上%1个进程在运行\n").arg(countProcess), QMessageBox::Ok);
}
源码
widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QtWin>
#include <QIcon>
#include <QString>
#include <QListWidget>
#include <QListWidgetItem>
#include <QTableWidgetItem>
#include <QHBoxLayout>
#include <QMessageBox>
#include <QDebug>
#include <QStandardItemModel>
#include <QTableWidget>
#include <QTableView>
#include <QSet> // !!! 使用 Set 过滤进程重复项 可注释相关代码尝试获取全部进程
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr);
~Widget();
public:
int getAllProcess();
private:
void getExtIcon();
void getProIcon();
private:
QListWidget *m_ExtListWidget;
QListWidget *m_ProListWidget;
QHBoxLayout *m_Hbox;
private:
QStringList m_ProList;
};
#endif // WIDGET_H
widget.cpp
#include "widget.h"
#include <iostream>
#include <windows.h>
#include <tlhelp32.h> //进程快照函数头文件
#include <string>
#include <stdio.h>
#include <tchar.h>
#include <Psapi.h>
#pragma comment (lib,"Psapi.lib")
using namespace std;
#ifdef UNICODE
#define QStringToTCHAR(x) (wchar_t*) x.utf16()
#define PQStringToTCHAR(x) (wchar_t*) x->utf16()
#define TCHARToQString(x) QString::fromUtf16((x))
#define TCHARToQStringN(x,y) QString::fromUtf16((x),(y))
#else
#define QStringToTCHAR(x) x.local8Bit().constData()
#define PQStringToTCHAR(x) x->local8Bit().constData()
#define TCHARToQString(x) QString::fromLocal8Bit((x))
#define TCHARToQStringN(x,y) QString::fromLocal8Bit((x),(y))
#endif
BOOL DosPathToNtPath(LPTSTR pszDosPath, LPTSTR pszNtPath)
{
TCHAR szDriveStr[500];
TCHAR szDrive[3];
TCHAR szDevName[100];
INT cchDevName;
INT i;
//检查参数
if (!pszDosPath || !pszNtPath)
return FALSE;
//获取本地磁盘字符串
if (GetLogicalDriveStrings(sizeof(szDriveStr), szDriveStr))
{
for (i = 0; szDriveStr[i]; i += 4)
{
if (!wcscmp(&(szDriveStr[i]), (L"A:\\")) || !wcscmp(&(szDriveStr[i]), _T(L"B:\\")))
continue;
szDrive[0] = szDriveStr[i];
szDrive[1] = szDriveStr[i + 1];
szDrive[2] = '\0';
if (!QueryDosDevice(szDrive, szDevName, 100))//查询 Dos 设备名
return FALSE;
cchDevName = lstrlen(szDevName);
if ((pszDosPath, szDevName, cchDevName) == 0)//命中
{
lstrcpy(pszNtPath, szDrive);//复制驱动器
lstrcat(pszNtPath, pszDosPath + cchDevName);//复制路径
return TRUE;
}
}
}
lstrcpy(pszNtPath, pszDosPath);
return FALSE;
}
//获取进程完整路径
BOOL GetProcessFullPath(DWORD dwPID, TCHAR pszFullPath[MAX_PATH], __out QString& str)
{
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPID);
if (!hProcess)
{
//QMessageBox::warning(NULL,"GetPathByProcessID","无权访问该进程");
str = "";
}
WCHAR filePath[MAX_PATH];
DWORD ret= GetModuleFileNameEx(hProcess, NULL, filePath, MAX_PATH) ;
QString file = QString::fromStdWString( filePath );
//QMessageBox::warning(NULL,"GetPathByProcessID ret=", QString::number(ret)+":"+file);
CloseHandle(hProcess);
str = ret == 0 ? "" : file;
return true;
}
string GetProcessInfo(__in HANDLE hProcess, __in WCHAR* processName)
{
PROCESSENTRY32* pinfo = new PROCESSENTRY32; //进程信息 (pinfo->dwSize = sizeof(PROCESSENTRY32);)
MODULEENTRY32* minfo = new MODULEENTRY32; //模块信息 (minfo->dwSize = sizeof(MODULEENTRY32);)
char shortpath[MAX_PATH]; //保存路径变量
int flag = Process32First(hProcess, pinfo); // 从第一个进程开始
while (flag) {
if (wcscmp(pinfo->szExeFile, processName) == 0) {
// 创建进程快照
HANDLE hModule = CreateToolhelp32Snapshot(
TH32CS_SNAPMODULE, //(DWORD) 快照返回的对象,TH32CS_SNAPMODULE 是指 "特定进程的使用模块的列表"
pinfo->th32ProcessID //(DWORD) 要获取快照进程的PID,当前进程/系统列表 快照时设为0
);
// 把第一个模块信息给 minfo
Module32First(
hModule, //(HANDLE) CreateToolhelp32Snapshot 的返回句柄
minfo // (LPMODULEENTRY32) 接收模块信息
);
// 把文件路径给 shortpath
GetShortPathName(
minfo->szExePath, // 文件路径(但最好不要用这个,因为这个碰到中文会出现乱码)
(LPWSTR)shortpath, // 用来接收 minfo->szExePath 兼容中文的值
256 // 缓冲区大小
);
return shortpath;
}
// 下一个进程
flag = Process32Next(hProcess, pinfo);
}
return NULL;
}
int Widget::getAllProcess()
{
int countProcess = 0; //当前进程数量计数变量
HANDLE hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); // 创建进程快照
PROCESSENTRY32W currentProcess; // 用来接收 hProcessSnap 的信息
currentProcess.dwSize = sizeof(currentProcess); //在使用这个结构之前,先设置它的大小
HANDLE hProcess = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);//给系统内的所有进程拍一个快照
if (hProcess == INVALID_HANDLE_VALUE)
{
printf("CreateToolhelp32Snapshot()调用失败!\n");
return -1;
}
bool bMore = Process32First(hProcessSnap, ¤tProcess); //获取第一个进程信息
while (bMore) {
QString str;
TCHAR szProcessName[MAX_PATH] = { 0 };
GetProcessFullPath(currentProcess.th32ProcessID, szProcessName, str);
m_ProList.append(str);
bMore = Process32Next(hProcessSnap, ¤tProcess); //遍历下一个
countProcess++;
}
CloseHandle(hProcess); //清除hProcess句柄
// QMessageBox::information(this,QString::fromLocal8Bit("检测完毕"),QString::fromLocal8Bit("共有以上%1个进程在运行\n").arg(countProcess), QMessageBox::Ok);
}
// 获取文件图标
HICON fileIcon(std::string extention)
{
HICON icon = NULL;
if (extention.length() > 0)
{
LPCSTR name = extention.c_str();
SHFILEINFOA info;
if (SHGetFileInfoA(name,
FILE_ATTRIBUTE_NORMAL,
&info,
sizeof(info),
SHGFI_SYSICONINDEX | SHGFI_ICON | SHGFI_USEFILEATTRIBUTES))
{
icon = info.hIcon;
}
}
return icon;
}
HICON QueryExeIcon(LPCTSTR lpszExePath)
{
HICON hIcon = NULL;
SHFILEINFO FileInfo;
DWORD_PTR dwRet = ::SHGetFileInfo(lpszExePath, 0, &FileInfo, sizeof(SHFILEINFO), SHGFI_ICON);
// 目标文件不存在
if (dwRet)
{
hIcon = FileInfo.hIcon;
}
return hIcon;
}
// 获取文件类型
std::string fileType(std::string extention)
{
std::string type = "";
if (extention.length() > 0)
{
LPCSTR name = extention.c_str();
SHFILEINFOA info;
if (SHGetFileInfoA(name,
FILE_ATTRIBUTE_NORMAL,
&info,
sizeof(info),
SHGFI_TYPENAME | SHGFI_USEFILEATTRIBUTES))
{
type = info.szTypeName;
}
}
return type;
}
// 获取文件夹图标
HICON folderIcon()
{
std::string str = "folder";
LPCSTR name = str.c_str();
HICON icon = NULL;
SHFILEINFOA info;
if (SHGetFileInfoA(name,
FILE_ATTRIBUTE_DIRECTORY,
&info,
sizeof(info),
SHGFI_SYSICONINDEX | SHGFI_ICON | SHGFI_USEFILEATTRIBUTES))
{
icon = info.hIcon;
}
return icon;
}
// 获取文件夹类型
std::string folderType()
{
std::string str = "folder";
LPCSTR name = str.c_str();
std::string type;
SHFILEINFOA info;
if (SHGetFileInfoA(name,
FILE_ATTRIBUTE_DIRECTORY,
&info,
sizeof(info),
SHGFI_TYPENAME | SHGFI_USEFILEATTRIBUTES))
{
type = info.szTypeName;
}
return type;
}
Widget::Widget(QWidget *parent)
: QWidget(parent)
{
setGeometry(200, 200, 800, 800);
setSizePolicy(QSizePolicy::Preferred,QSizePolicy::Preferred);
m_Hbox = new QHBoxLayout(this);
m_ExtListWidget = new QListWidget;
m_ExtListWidget->setSizePolicy(QSizePolicy::Maximum,QSizePolicy::Preferred);
m_ProListWidget = new QListWidget;
m_ProListWidget->setSizePolicy(QSizePolicy::Preferred,QSizePolicy::Preferred);
m_Hbox->addWidget(m_ExtListWidget);
m_Hbox->addWidget(m_ProListWidget);
m_Hbox->setStretch(0,3);
m_Hbox->setStretch(1,7);
getExtIcon();
getProIcon();
}
Widget::~Widget()
{
}
void Widget::getExtIcon()
{
m_ExtListWidget->setViewMode(QListView::ListMode);
std::string strArray[13] = {"folder", ".exe", ".zip", ".har", ".hwl", ".accdb",
".xlsx", ".pptx", ".docx", ".txt", ".h", ".cpp", ".pro"};
int nCount = sizeof(strArray) / sizeof(std::string);
for (int i = 0; i < nCount ; ++i)
{
// 获取图标、类型
QPixmap pixmap;
std::string type;
int nPos = -1;
nPos = strArray[i].find(".");
if (nPos >= 0)
{
// Qt4:QPixmap::fromWinHICON(icon)
pixmap = QtWin::fromHICON(fileIcon(strArray[i]));
type = fileType(strArray[i]);
}
else
{
pixmap = QtWin::fromHICON(folderIcon());
type = folderType();
}
QIcon icon;
icon.addPixmap(pixmap);
QString strType = QString::fromLocal8Bit(type.c_str());
// 添加单元项
QListWidgetItem *pItem = new QListWidgetItem;
pItem->setIcon(icon);
pItem->setText(strType);
m_ExtListWidget->addItem(pItem);
}
}
void Widget::getProIcon()
{
getAllProcess();
QSet<QString> SetList;
for(auto it : m_ProList)
{
SetList.insert(it);
}
int nCount = SetList.size();
foreach(const QString& value, SetList)
{
if(value.isEmpty())
{
continue;
}
// 获取图标、类型
QPixmap pixmap;
std::string type;
// Qt4:QPixmap::fromWinHICON(icon)
pixmap = QtWin::fromHICON(QueryExeIcon(value.toStdWString().c_str()));
type = fileType(value.toStdString());
QIcon icon;
icon.addPixmap(pixmap);
QString strType = value;
// 添加单元项
QListWidgetItem *pItem = new QListWidgetItem;
pItem->setCheckState(Qt::Unchecked);
pItem->setIcon(icon);
pItem->setText(strType);
m_ProListWidget->addItem(pItem);
}
}
更多推荐
已为社区贡献2条内容
所有评论(0)