【问题标题】:QProcess always returns -2 when running a valid command运行有效命令时,QProcess 总是返回 -2
【发布时间】:2023-12-21 12:09:02
【问题描述】:

我正在用 qt 编写一个程序,它将在 windows 中执行命令。

这是我用来尝试让命令工作的方法。

bool FirmwareUpdater::RunCommand( QString& command, QStringList& args, int expectedCode )
{
    QProcess *proc = new QProcess();
    proc->setWorkingDirectory ( "C:\\windows\\" );
    int exitCode = proc->execute(command, args );
    proc->waitForFinished();
    this->stream << command << " " << exitCode << "\n";
    return ( exitCode == expectedCode );
}

如果我跑了

QString command = "ping";
QStringList args;

args << "localhost";
RunCommand( command, args );

它工作正常,它返回 0;

但如果我尝试任何其他 Windows 实用程序,它会返回 -2。现在我正试图让 pnpUtil 也能正常工作。

QString command = qgetenv( "WINDIR" ) + "\\System32\\PnPUtil.exe";
QStringList args;

args << "-a";
args << updateDriver;

我有代码向我打印带有参数的命令,如果我手动运行该命令,它就可以工作。但在 qt 中却没有。

也许我做错了什么。如果没有 QProcess,还有其他方法可以做到这一点吗?

我也尝试过调用静态肉类

QProcess::startDetached

但这对我来说也失败了。

【问题讨论】:

  • 我没有使用QT,但是会不会是权限问题?如果你不想使用 QProcess,你总是可以使用 CreateProcess()GetLastError()
  • 我搞砸了这些,但程序甚至没有启动。它只是失败,好像它找不到 exe。但它就在那里。
  • Sysinternals 的进程监控实用程序可能会帮助您找出问题所在 - 它会显示从正在使用的 Windows API 返回的错误代码(我假设是CreateProcess())。

标签: c++ qt qprocess


【解决方案1】:

我相信您的程序是 32 位并在 64 位 Windows 下运行。当您运行 32 位程序时,PnPUtil.exe 不在c:\windows\system32 中,这就是QProcess 无法启动它的原因。它在其他地方,例如,我的位于C:\Windows\WinSxS\amd64_microsoft-windows-pnputil_31bf3856ad364e35_6.3.9600.16384_none_ee22229c907e8ce2。您可以在命令提示符中运行 c:\windows\system32\PnPUtil.exe,因为 cmd.exe 是 64 位程序。

您可以尝试herehere 的解决方案。

更新 1

在 32 位或 64 位 Windows 下运行 PnPUtil 和 Ping 的示例代码。

#include <QtCore>

void run( QString command, QStringList args )
{
    QProcess *proc = new QProcess();
    //proc->setWorkingDirectory ( "C:\\windows\\" );
    qDebug() << "\n===========================================";
    qDebug() << "Running " << command << args.join(' ');
    qDebug() << (QFile::exists(command) ? "File exists: " : "File may not exist:") << command;
    int exitCode = proc->execute(command, args );
    proc->waitForFinished();
    qDebug() << "\nResult";
    qDebug() << "======";
    qDebug() << "proc->execute()    =" << exitCode;
    qDebug() << "proc->exitCode()   =" << proc->exitCode();
    qDebug() << "proc->exitStatus() =" << proc->exitStatus();    
}

int main(int argc, char *argv[])
{
    QStringList pnpUtilArg("-?");
    QStringList pingArg("google.com");

    run( qgetenv( "WINDIR" ) + "\\sysnative\\pnputil.exe", pnpUtilArg);
    run( qgetenv( "WINDIR" ) + "\\system32\\pnputil.exe", pnpUtilArg);
    run( qgetenv( "WINDIR" ) + "\\system32\\ping.exe", pingArg);
    run( "ping.exe", pingArg);

    getchar();
}

【讨论】:

  • 不错的收获。另一个简单的解决方法是尝试执行c:\windows\sysnative\pnputil.exe。不过,我不知道这是否是一个好主意。
  • 尝试在 32 位系统上运行它,但没有成功。
  • @Snhp9,你的意思是你不能在 32 位 Windows 下运行 c:\windows\sysnative\pnputil.exe 吗?嗯,pnputil 不在 32 位窗口下哈哈哈。我猜你的 32 位程序需要知道它运行的操作系统的位数。试试这个:1) 在 32 位 Windows 下,运行 c:\windows\system32\pnputil.exe 2) 在 64 位 Windows 下,运行 c:\windows\sysnative\pnputil.exe
  • @Snhp9:关于如何检查操作系统的位数,试试这个answer。另一个不关心位数的解决方案可能是:运行c:\windows\sysnative\pnputil.exe(如果存在)。否则运行c:\windows\system32\pnputil.exe
  • 我都试过了,我硬编码了 32 位的路径。将程序编译成 32 位,然后在 32 位计算机上运行。我对 64 位也做了同样的事情。它甚至使用 ping.exe 来执行此操作。即使我指定了 ping 的完整路径,它也不起作用。我可以让它工作的唯一方法是将 ping.exe 放在与程序相同的目录中并且有效。由于所有依赖项,我无法使用 pnputils 做到这一点。
最近更新 更多