QT 管理win系统服务


以管理员权限运行程序




#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);
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值