在Qt跨平台开发中,在Windows平台上经常有开启新的进程来执行任务的情况,这里又分为2种,一种是不需要超级管理员权限的,可以直接使用QProcess
来完成;还有一种就是需要管理员权限来执行一些脚本。
比如现在想在软件打开时修改注册表,bat
脚本如下:
bash
@echo "auto create dump"
echo Yes | reg add "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\Windows Error Reporting\LocalDumps"
echo Yes | reg add "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\Windows Error Reporting\LocalDumps\FTIRDasAnalyzer.exe"
echo Yes | reg add "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\Windows Error Reporting\LocalDumps\FTIRDasAnalyzer.exe" /v DumpFolder /t REG_EXPAND_SZ /d "C:\DumpFile" /f
echo Yes | reg add "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\Windows Error Reporting\LocalDumps\FTIRDasAnalyzer.exe" /v DumpType /t REG_DWORD /d 2 /f
echo Yes | reg add "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\Windows Error Reporting\LocalDumps\FTIRDasAnalyzer.exe" /v DumpCount /t REG_DWORD /d 10 /f
这时需要使用Windows
平台的API,先加上windows.h
头文件:
arduino
#include <windows.h>
然后使用SHELLEXECUTEINFO
相关API即可:
ini
void UACrunProcess(QString Path) {
QFile file(Path);
if (!file.exists()) {
logWarn() << "create dump bat path is not exists";
return;
}
std::wstring wstr = Path.toStdWString();
const wchar_t* filePtr = wstr.c_str();
SHELLEXECUTEINFO sei = { sizeof(SHELLEXECUTEINFO) };
sei.lpVerb = TEXT("runas");
sei.lpFile = filePtr;
sei.nShow = SW_SHOWNORMAL;//without this,the windows will be hiden
// sei.nShow = SW_HIDE;
if (!ShellExecuteEx(&sei)) {
DWORD dwStatus = GetLastError();
if (dwStatus == ERROR_CANCELLED) {
logWarn() << "bat execute canceld";
} else if (dwStatus == ERROR_FILE_NOT_FOUND) {
logWarn() << "bat execute not found execute file";
}
}
}
上面代码比较简单,但是有几点需要注意:
- 对于
QString
类型的字符串,需要转换为wchar_t*
类型。 - 在启动
Qt Creator
时必须以管理员权限启动。 - 在执行过程中,可以通过
echo Yes | ...
的方式给指令在执行时赋默认值,否则黑色的命令行弹窗不会消失,会影响美观或者升级等操作。