#include "mainwindow.h" #include <QApplication> #include <windows.h> #include <wtsapi32.h> #pragma comment(lib, "Wtsapi32.lib") int main(int argc, char *argv[]) { QApplication a(argc, argv); HANDLE hToken = NULL; DWORD dwSessionId = WTSGetActiveConsoleSessionId(); if (!WTSQueryUserToken(dwSessionId, &hToken)) { QMessageBox::warning(nullptr, QStringLiteral("错误"), QStringLiteral("获取用户令牌失败!")); return -1; } HANDLE mutex = ::CreateMutex(Q_NULLPTR,true,(LPCWSTR)qApp->applicationName().toStdWString().c_str()); if(GetLastError() == ERROR_ALREADY_EXISTS) { QMessageBox waringBox(QMessageBox::Warning,QStringLiteral("警告"),QStringLiteral("程序[文本数据同步客户端]只能运行一个!")); waringBox.setButtonText(QMessageBox::Ok,QStringLiteral("确定")); waringBox.setStandardButtons(QMessageBox::Ok); waringBox.exec(); ::CloseHandle(mutex); CloseHandle(hToken); // 添加关闭句柄语句 return 0; } else { ::ReleaseMutex(mutex); } STARTUPINFO si; ZeroMemory(&si, sizeof(si)); si.cb = sizeof(si); si.lpDesktop = (LPWSTR)L"winsta0\\default"; PROCESS_INFORMATION pi; ZeroMemory(&pi, sizeof(pi)); if (!CreateProcessAsUser(hToken, NULL, (LPWSTR)qApp->applicationFilePath().toStdWString().data(), NULL, NULL, FALSE, CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi)) { QMessageBox::warning(nullptr, QStringLiteral("错误"), QStringLiteral("创建进程失败!")); CloseHandle(hToken); return -1; } CloseHandle(hToken); MainWindow w; w.show(); return a.exec(); } 以上是限制程序在windows Server2016系统中多个用户界面也只能运行一个程序的QT C++代码,: 但是如果在windows Server2016系统中两个用户界面可同时运行程序。 在还未有程序运行时,运行第一个也会直接提示 "获取用户令牌失败!",程序直接关闭,请帮我修复后给我完整代码
时间: 2024-01-17 15:06:10 浏览: 70
最终的mainwindowh文件如下。-QT实验设计PPT
以下是修复后的完整代码:
```
#include "mainwindow.h"
#include <QApplication>
#include <windows.h>
#include <wtsapi32.h>
#pragma comment(lib, "Wtsapi32.lib")
int main(int argc, char *argv[]) {
QApplication a(argc, argv);
HANDLE hToken = NULL;
DWORD dwSessionId = WTSGetActiveConsoleSessionId();
if (dwSessionId == 0xFFFFFFFF) {
QMessageBox::warning(nullptr, QStringLiteral("错误"), QStringLiteral("获取会话ID失败!"));
return -1;
}
if (!WTSQueryUserToken(dwSessionId, &hToken)) {
QMessageBox::warning(nullptr, QStringLiteral("错误"), QStringLiteral("获取用户令牌失败!"));
return -1;
}
HANDLE mutex = ::CreateMutex(Q_NULLPTR, true, (LPCWSTR)qApp->applicationName().toStdWString().c_str());
if (!mutex) {
QMessageBox::warning(nullptr, QStringLiteral("错误"), QStringLiteral("创建互斥量失败!"));
CloseHandle(hToken);
return -1;
}
if (GetLastError() == ERROR_ALREADY_EXISTS) {
QMessageBox waringBox(QMessageBox::Warning,QStringLiteral("警告"),QStringLiteral("程序[文本数据同步客户端]只能运行一个!"));
waringBox.setButtonText(QMessageBox::Ok,QStringLiteral("确定"));
waringBox.setStandardButtons(QMessageBox::Ok);
waringBox.exec();
::CloseHandle(mutex);
CloseHandle(hToken);
return 0;
}
STARTUPINFO si;
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
si.lpDesktop = (LPWSTR)L"winsta0\\default";
PROCESS_INFORMATION pi;
ZeroMemory(&pi, sizeof(pi));
if (!CreateProcessAsUser(hToken, NULL, (LPWSTR)qApp->applicationFilePath().toStdWString().data(), NULL, NULL, FALSE, CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi)) {
QMessageBox::warning(nullptr, QStringLiteral("错误"), QStringLiteral("创建进程失败!"));
CloseHandle(mutex);
CloseHandle(hToken);
return -1;
}
CloseHandle(hToken);
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
::ReleaseMutex(mutex);
MainWindow w;
w.show();
return a.exec();
}
```
主要修复了以下问题:
1. 修复了获取会话ID失败时没有处理的问题。
2. 修复了创建互斥量失败时没有处理的问题。
3. 修复了创建进程失败时没有关闭句柄的问题。
4. 添加了关闭进程句柄和线程句柄的语句。
5. 添加了释放互斥量的语句。
阅读全文