我需要在我的应用程序中运行自定义可执行文件。我有以下代码来运行我的过程:
QFileInfo fiUpdator(updatorLocation);
if(!fiUpdator.isExecutable()) {
qWarning() << "Maintenance Tool is not an executable";
return;
}
qDebug() << "Starting updator app";
QString pid = QString::number(qApp->applicationPid());
QString appName = qApp->applicationName();
QProcess *p = new QProcess;
connect(p, &QProcess::started, this, [this](){
qDebug() << "Updator Process Started";
});
connect(p, &QProcess::errorOccurred, this, [this](QProcess::ProcessError error){
qDebug() << "Error Occurred : " << error;
});
connect(p, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished), this, [this, p](){
qDebug() << "Finished Updator Process";
QString str("Exit [" + QString::number(p->exitCode()) + "] " + p->exitStatus());
qDebug() << str;
});
connect(p, &QProcess::readyReadStandardError, this, [this, p](){
QByteArray ba = p->readAllStandardError();
qDebug() << "Error:\n" << QString::fromUtf8(ba);
});
connect(p, &QProcess::readyReadStandardOutput, this, [this, p](){
QByteArray ba = p->readAllStandardOutput();
qDebug() << "Output:\n" << QString::fromUtf8(ba);
});
connect(p, &QProcess::stateChanged, this, [this](QProcess::ProcessState newState){
qDebug() << "State Changed : " << newState;
});
p->start(
updatorLocation,
QStringList()
<< pid
<< appName
<< newFilePath
<< oldFilePath);
该应用程序(一个qt控制台应用程序使用来运行,期望使用]
start "" "C:\Path\To\AwesomeConsoleApp.exe"
这将短暂打开一个带有编码输出的新CMD窗口,或者打开cmd.exe
并运行
C:\Path\To\AwesomeConsoleApp.exe
在同一stdout
窗口中将输出显示到cmd
。
过程信号触发如下:
stateChanged Starting
stateChanged Running
QProcess::started
stateChanged NotRunning
QProcess::finished
:输出Exit[1] 0
我尝试将.exe
替换为C:\Windows\System32\calc.exe
,然后启动就没有问题。
这是否意味着我的自定义可执行文件有问题?
出于删除问题的考虑,但以防万一,可以在以后提供帮助的人。]
问题不在于调用应用程序代码或被调用应用程序的代码(即上面显示的MaintenanceTool
)。相反,这是MaintenanceTool
特权的问题。
所以,我的MaintenanceTool
需要管理特权
MaintenanceTool
可以运行。为此,我使用QProcess来方便启动MaintenanceTool
应用程序。 [[Note
:为了获得行政特权,我以this为灵感来开展我的工作。我尝试将以下各项与QProcess
组合使用,请注意,这些都不适合以管理员身份运行应用程序
QProcess::startDeteched("cmd.exe", QStringList() << "/C" << "/path/to/mtool.exe -arg1 -arg2"); QProcess::startDeteched("cmd.exe", QStringList() << "/C" << "/path/to/mtool.exe -arg1 -arg2"); QProcess::startDeteched("start.exe", QStringList() << "" << "/path/to/mtool.exe -arg1 -arg2"); QProcess::startDeteched("C:\Windows\System32\cmd.exe", QStringList() << "/C" << "/path/to/mtool.exe -arg1 -arg2"); QProcess::startDeteched("C:\Windows\System32\cmd.exe", QStringList() << "/C" << "/path/to/mtool.exe -arg1 -arg2"); QProcess::startDeteched("/path/to/mtool.exe", QStringList() << "" << "-arg1" << "-arg2");
我还创建了一个
QProcess *p
,添加了readStandardOutput()
等(如下所示),它们提供了Exit Code 0
。此外,我还尝试将所有命令输出到应用程序,并在调试MaintenaceTool
应用程序时将它们作为参数手动调用。用manual arguments运行它使MaintenanceTool
运行(使用Qt调试模式)并按预期工作,这使我感到非常困惑(但没有显示管理特权对话框弹出窗口-当时没有注意到)。
[查看QProcess::startDetached()
实际的Qt代码,我终于遇到了一条消息error string
(从未作为实际输出或errorString
发送),但存储在变量中。本质上,它提到它无法启动需要管理员特权的应用程序。因此,我搜索并发现了ShellExecuteEx的here示例。
[我的实现]的ShellExecuteEx
]
QString args = QString(“ \”%1 \“ \”%2 \“ \”%3 \“ \”%4 \“ \”%5 \“”)。arg(pid).arg(appName) .arg(logLocation).arg(newFilePath).arg(oldFilePath);
LPCWSTR文件= reinterpret_cast(updatorLocation.utf16());
LPCWSTR arg = reinterpret_cast(args.utf16());
SHELLEXECUTEINFO ShExecInfo = {0};
ShExecInfo.cbSize = sizeof(SHELLEXECUTEINFO);
ShExecInfo.fMask = SEE_MASK_NOCLOSEPROCESS;
ShExecInfo.hwnd = NULL;
ShExecInfo.lpVerb = L“ runas”;
ShExecInfo.lpFile =文件;
ShExecInfo.lpParameters = arg;
ShExecInfo.lpDirectory = NULL;
ShExecInfo.nShow = SW_SHOW;
ShExecInfo.hInstApp = NULL;
ShellExecuteEx(&ShExecInfo);
使用
ShellExecuteEx
解决了我的问题,并允许应用程序正常运行,启动应用程序时弹出runas
管理对话框。我希望这对某人有帮助!