以管理员权限运行程序
#include "QService.h"
#include "Psapi.h"
#include <QDebug>
#include <QHeaderView>
#include <QCheckBox>
QService::QService(QWidget *parent)
: QMainWindow(parent)
{
ui.setupUi(this);
Init();
}
QService::~QService()
{
CloseServiceHandle(mHSCM);
if (mBuf != nullptr) {
delete[] mBuf;
mBuf = nullptr;
}
if (RefreshTimer != nullptr && RefreshTimer->isActive())
{
RefreshTimer->stop();
delete RefreshTimer;
RefreshTimer = nullptr;
}
}
void QService::Init()
{
mHSCM = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS | SERVICE_QUERY_STATUS);
QStringList headers;
headers << " " << QString(u8"序号") << QString(u8"服务名称") << QString(u8"状态") << QString("PID");
ui.SerTabWdt->setColumnCount(5);
ui.SerTabWdt->setHorizontalHeaderLabels(headers);
ui.SerTabWdt->horizontalHeader()->setSectionResizeMode(QHeaderView::Interactive);
ui.SerTabWdt->verticalHeader()->setSectionResizeMode(QHeaderView::Stretch);
ui.SerTabWdt->setColumnWidth(0, 40);
ui.SerTabWdt->setColumnWidth(1, 80);
ui.SerTabWdt->setColumnWidth(2, 220);
ui.SerTabWdt->setColumnWidth(3, 80);
ui.SerTabWdt->setColumnWidth(4, 80);
//设置表头字体加粗
QFont font = ui.SerTabWdt->horizontalHeader()->font();
font.setBold(true);
ui.SerTabWdt->horizontalHeader()->setFont(font);
ui.SerTabWdt->horizontalHeader()->setStretchLastSection(true); //设置充满表宽度
//ui.SerTabWdt->verticalHeader()->setResizeMode(QHeaderView::ResizeToContents);
ui.SerTabWdt->verticalHeader()->setDefaultSectionSize(30); //设置行距
ui.SerTabWdt->setFrameShape(QFrame::NoFrame); //设置无边框
ui.SerTabWdt->verticalHeader()->setVisible(false); //设置垂直头不可见
ui.SerTabWdt->setSelectionBehavior(QAbstractItemView::SelectRows); //设置选择行为时每次选择一行
ui.SerTabWdt->setEditTriggers(QAbstractItemView::NoEditTriggers); //设置不可编辑
ui.SerTabWdt->horizontalHeader()->resizeSection(0, 40); //设置表头第一列的宽度为50
ui.SerTabWdt->horizontalHeader()->setFixedHeight(25); //设置表头的高度
ui.SerTabWdt->setStyleSheet("selection-background-color:lightblue;"); //设置选中背景色
ui.SerTabWdt->horizontalHeader()->setStyleSheet("QHeaderView::section{background:skyblue;}"); //设置表头背景色
RefreshTable();
RefreshTimer = new QTimer(this);
RefreshTimer->setInterval(3000);
connect(RefreshTimer, &QTimer::timeout, this, &QService::on_RefreshBtn_clicked);
// RefreshTimer->start();
}
void QService::Error(int ret)
{
if (ret == 0) {
switch (GetLastError()) {
case ERROR_ACCESS_DENIED:
qDebug() << "ERROR_ACCESS_DENIED";
break;
case ERROR_MORE_DATA:
qDebug() << "ERROR_MORE_DATA";
break;
case ERROR_INVALID_PARAMETER:
qDebug() << "ERROR_INVALID_PARAMETER";
break;
case ERROR_INVALID_HANDLE:
qDebug() << "ERROR_INVALID_HANDLE";
break;
case ERROR_INVALID_LEVEL:
qDebug() << "ERROR_INVALID_LEVEL";
break;
case ERROR_SHUTDOWN_IN_PROGRESS:
qDebug() << "ERROR_SHUTDOWN_IN_PROGRESS";
break;
default:
qDebug() << "other error";
break;
}
}
}
void QService::RefreshTable()
{
DWORD needLen, serviceNum, result, type;
needLen = 2;
result = 0;
BOOL ret = 0;
type = SERVICE_WIN32;
ret = EnumServicesStatusEx(mHSCM, SC_ENUM_PROCESS_INFO, type
, SERVICE_STATE_ALL, NULL, 0, &needLen
, &serviceNum, NULL, NULL);
Error(ret);
needLen += sizeof(ENUM_SERVICE_STATUS_PROCESS);
mBuf = new BYTE[needLen];
// EnumServicesStatusExA 枚 *务API
ret = EnumServicesStatusEx(mHSCM, SC_ENUM_PROCESS_INFO, type
, SERVICE_STATE_ALL, reinterpret_cast<LPBYTE>(mBuf), needLen, &needLen
, &serviceNum, &result, NULL);
Error(ret);
if (result != 0) {
if (mBuf != nullptr) {
delete[] mBuf;
mBuf = nullptr;
}
needLen += sizeof(LPENUM_SERVICE_STATUS_PROCESS);
mBuf = new BYTE[needLen];
memset(mBuf,0x0, needLen);
ret = EnumServicesStatusEx(mHSCM, SC_ENUM_PROCESS_INFO, type
, SERVICE_STATE_ALL, mBuf, needLen, &needLen
, &serviceNum, &result, NULL);
Error(ret);
}
LPENUM_SERVICE_STATUS_PROCESS p = (LPENUM_SERVICE_STATUS_PROCESS)mBuf;
if (ret == 0) {
qDebug() << "获取服务失败";
}
else {
qDebug() << "获取服务成功";
// 往表格中添加数据
for (DWORD i = 0; i < serviceNum; i++) {
ui.SerTabWdt->insertRow(i);
QCheckBox *CheckBox = new QCheckBox(ui.SerTabWdt);
QSize size(39, 39);
CheckBox->setFixedSize(size);
CheckBox->setCheckState(Qt::Unchecked);
//创建单击选中的信号槽连接
QObject::connect(CheckBox, &QCheckBox::clicked, this, [=]()
{
//AlarmTableItemChoosed(row, 0);
});
ui.SerTabWdt->setCellWidget(i, 0, CheckBox);//row行,0列
ui.SerTabWdt->setItem(i, 1, new QTableWidgetItem(QString::number(i + 1)));
ui.SerTabWdt->setItem(i, 2, new QTableWidgetItem(QString::fromStdWString(p[i].lpServiceName)));
QTableWidgetItem* item;
switch (p[i].ServiceStatusProcess.dwCurrentState) {
case SERVICE_PAUSED:
item = new QTableWidgetItem(u8"暂停");
break;
case SERVICE_STOPPED:
item = new QTableWidgetItem(u8"停止");
break;
case SERVICE_RUNNING:
item = new QTableWidgetItem(u8"运行");
break;
default:
item = new QTableWidgetItem(u8"其他");
break;
}
ui.SerTabWdt->setItem(i, 3, item);
ui.SerTabWdt->setItem(i, 4, new QTableWidgetItem(QString::number(p[i].ServiceStatusProcess.dwProcessId)));
}
// delete
}
//CloseServiceHandle(mHSCM);
}
void QService::on_RefreshBtn_clicked()
{
int rowNum = ui.SerTabWdt->rowCount();
for (int i = 0;i < rowNum;i++)
{
ui.SerTabWdt->removeRow(0);
rowNum = ui.SerTabWdt->rowCount();
}
RefreshTable();
}
void QService::on_StartBtn_clicked()
{
// 启动服务
int row = ui.SerTabWdt->currentRow();
LPENUM_SERVICE_STATUS_PROCESSA p = reinterpret_cast<LPENUM_SERVICE_STATUS_PROCESSA>(mBuf);
if (p[row].ServiceStatusProcess.dwCurrentState == SERVICE_RUNNING)
return;
QString s = ui.SerTabWdt->item(row, 2)->text();
LPCWSTR name = reinterpret_cast<LPCWSTR>(s.data());
SC_HANDLE service = OpenService(mHSCM, name, SERVICE_ALL_ACCESS);
Error(0);
if (service == nullptr) {
qDebug() << "打开服务失败";
return;
}
// StartServiceA启动服务API
BOOL ret = StartService(service, 0, nullptr);
if (ret) {
qDebug() << "启动服务成功";
on_RefreshBtn_clicked();
p[row].ServiceStatusProcess.dwCurrentState = SERVICE_RUNNING;
}
else {
qDebug() << "启动服务失败";
}
}
void QService::on_StopBtn_clicked()
{
// 停止服务
int row = ui.SerTabWdt->currentRow();
LPENUM_SERVICE_STATUS_PROCESSA p = reinterpret_cast<LPENUM_SERVICE_STATUS_PROCESSA>(mBuf);
if (p[row].ServiceStatusProcess.dwCurrentState == SERVICE_STOPPED)
return;
QString s = ui.SerTabWdt->item(row, 2)->text();
LPCWSTR name = reinterpret_cast<LPCWSTR>(s.data());
if (name == nullptr)
return;
SC_HANDLE service = OpenService(mHSCM, name, SERVICE_ALL_ACCESS);
if (service == nullptr) {
qDebug() << "打开服务失败";
return;
}
SERVICE_STATUS status;
// StartServiceA停止服务API
BOOL ret = ControlService(service, SERVICE_CONTROL_STOP, &status);
if (ret) {
qDebug() << "停止服务成功";
QTableWidgetItem *item = ui.SerTabWdt->takeItem(row, 3);
ui.SerTabWdt->setItem(row, 3, new QTableWidgetItem(u8"停止"));
ui.SerTabWdt->setItem(row, 4, new QTableWidgetItem(u8"0"));
p[row].ServiceStatusProcess.dwCurrentState = SERVICE_STOPPED;
}
else {
qDebug() << "停止服务失败";
}
}
// 根据进程iD获取进程名
QString QService::ShowProcName(uint32_t pid)
{
char tempProcName[MAX_PATH] = { 0 };
//必须具有的权限
HANDLE processHandle = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pid);
if (processHandle == NULL) {
return "";
}
auto len = GetModuleBaseNameA(processHandle, NULL, tempProcName, MAX_PATH);
if (len == 0) {
printf("Get base namefailed, err: %u", GetLastError());
}
printf("%s\n", tempProcName);
CloseHandle(processHandle);
return QString(tempProcName);
}