运行 带有 QProcess 的自定义可执行文件立即退出,退出代码为 1
Run custom executable with QProcess exiting immediately with exit code 1
我需要在我的应用程序中 运行 自定义可执行文件。我有以下代码 运行 我的过程:
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 window 和编码输出,或者打开 cmd.exe
和 运行ning
C:\Path\To\AwesomeConsoleApp.exe
显示输出到 stdout
在同一个 cmd
window.
进程信号触发如下:
stateChanged Starting
stateChanged Running
QProcess::started
stateChanged NotRunning
QProcess::finished
: 输出 Exit[1] 0
我尝试用 C:\Windows\System32\calc.exe
替换 .exe
来启动并且它启动没有问题。
这是否意味着我的自定义可执行文件有问题?
想删除这个问题,但万一它有用,我会post一个可能对以后的人有帮助的答案。
问题不在调用应用程序代码或被调用应用程序的代码中(即如上所示的 MaintenanceTool
)。相反,这是 MaintenanceTool
权限的问题。
所以,我的 MaintenanceTool
需要 管理权限 才能执行。我的调用应用程序 运行 没有管理权限,但我的 MaintenanceTool
有。为此,我使用 QProcess 来帮助启动 MaintenanceTool
应用程序。
注意:为了获得管理权限,我使用 this 作为灵感来开始我的工作。
我尝试了以下与 QProcess
的组合,请注意,其中 none 对 运行 将应用程序作为管理员 有效!
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
运行ning(使用 Qt 调试模式)并按预期工作,这让我很困惑(但没有显示管理员权限对话框弹出窗口- 当时没注意到)。
查看 QProcess::startDetached()
实际 Qt 代码,我终于遇到了一条消息 error string
(从未作为实际输出或 errorString
发送),但存储在一个变量。本质上,它提到它无法启动需要管理员权限的应用程序。因此,我搜索并找到了ShellExecuteEx example found here。
我的实施 ShellExecuteEx
QString args = QString("\"%1\" \"%2\" \"%3\" \"%4\" \"%5\"").arg(pid).arg(appName).arg(logLocation).arg(newFilePath).arg(oldFilePath);
LPCWSTR file = 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 = file;
ShExecInfo.lpParameters = arg;
ShExecInfo.lpDirectory = NULL;
ShExecInfo.nShow = SW_SHOW;
ShExecInfo.hInstApp = NULL;
ShellExecuteEx(&ShExecInfo);
使用 ShellExecuteEx
解决了我的问题并允许应用程序 运行 没有问题,应用程序启动时弹出 runas
管理对话框。
希望对大家有所帮助!
我需要在我的应用程序中 运行 自定义可执行文件。我有以下代码 运行 我的过程:
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 window 和编码输出,或者打开 cmd.exe
和 运行ning
C:\Path\To\AwesomeConsoleApp.exe
显示输出到 stdout
在同一个 cmd
window.
进程信号触发如下:
stateChanged Starting
stateChanged Running
QProcess::started
stateChanged NotRunning
QProcess::finished
: 输出Exit[1] 0
我尝试用 C:\Windows\System32\calc.exe
替换 .exe
来启动并且它启动没有问题。
这是否意味着我的自定义可执行文件有问题?
想删除这个问题,但万一它有用,我会post一个可能对以后的人有帮助的答案。
问题不在调用应用程序代码或被调用应用程序的代码中(即如上所示的 MaintenanceTool
)。相反,这是 MaintenanceTool
权限的问题。
所以,我的 MaintenanceTool
需要 管理权限 才能执行。我的调用应用程序 运行 没有管理权限,但我的 MaintenanceTool
有。为此,我使用 QProcess 来帮助启动 MaintenanceTool
应用程序。
注意:为了获得管理权限,我使用 this 作为灵感来开始我的工作。
我尝试了以下与 QProcess
的组合,请注意,其中 none 对 运行 将应用程序作为管理员 有效!
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
运行ning(使用 Qt 调试模式)并按预期工作,这让我很困惑(但没有显示管理员权限对话框弹出窗口- 当时没注意到)。
查看 QProcess::startDetached()
实际 Qt 代码,我终于遇到了一条消息 error string
(从未作为实际输出或 errorString
发送),但存储在一个变量。本质上,它提到它无法启动需要管理员权限的应用程序。因此,我搜索并找到了ShellExecuteEx example found here。
我的实施 ShellExecuteEx
QString args = QString("\"%1\" \"%2\" \"%3\" \"%4\" \"%5\"").arg(pid).arg(appName).arg(logLocation).arg(newFilePath).arg(oldFilePath);
LPCWSTR file = 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 = file;
ShExecInfo.lpParameters = arg;
ShExecInfo.lpDirectory = NULL;
ShExecInfo.nShow = SW_SHOW;
ShExecInfo.hInstApp = NULL;
ShellExecuteEx(&ShExecInfo);
使用 ShellExecuteEx
解决了我的问题并允许应用程序 运行 没有问题,应用程序启动时弹出 runas
管理对话框。
希望对大家有所帮助!