Qt5:使用QProcess :: startDetached调用.bat文件在System32中找不到程序

时间:2016-09-27 18:40:49

标签: c++ windows qt batch-file

我有一个带有按钮的小型Qt GUI程序,它启动一个.bat文件。

调用.bat的重要部分是:

void MainWindow::on_pushButton_clicked()
{
    int r = QMessageBox::warning(this, tr("Shutdown System"),
    tr("Do you want to close the program and the system?"),
    QMessageBox::Yes | QMessageBox::Default,
    QMessageBox::No,
    QMessageBox::Cancel | QMessageBox::Escape);

    if (r == QMessageBox::Yes){
        QProcess::startDetached("cmd /C shutdown_all.bat");
    }
}

我打算拨打位于C:\Windows\System32\psshutdown.exe的{​​{3}},当然还有PATH

我把它放在.bat中用于测试目的:

cd C:\Windows\System32
psshutdown
PAUSE

单独调用.bat文件时,似乎找到程序并打印有关它的信息,但是当我使用该按钮调用该程序时,它找不到psshutdown.exe

结果的捕获:

使用Qt程序调用.bat: PSShutdown

双击调用.bat(预期结果): .bat called from Qt program

在将echo %PATH%添加到.bat时,两个版本的路径似乎都打印好了。知道什么可能是错的吗?

这已在Qt 5.5和5.7,调试和发布模式下在两台不同的计算机上进行了测试。

如果需要,我可以提供完整的源代码,但它只是一个带有添加按钮的Qt Widgets Aplication,使用Qt Creator中的模板。

1 个答案:

答案 0 :(得分:2)

psshutdown.exe是Windows上通常不存在的可执行文件。它是Windows Sysinternals的工具,需要手动下载并复制到任何目录。

在64位Windows上,64位应用程序访问%SystemRoot%\System32中的64位应用程序和动态链接库。

但是,在%SystemRoot%\SysWOW64访问%SystemRoot%\System32以运行可执行文件或加载DLL时,Windows File System Redirector会将在64位Windows上运行的x86应用程序重定向到32位系统目录if exist %SystemRoot%\System32\psshutdown.exe ( %SystemRoot%\System32\psshutdown.exe ) else if exist %SystemRoot%\Sysnative\psshutdown.exe ( %SystemRoot%\Sysnative\psshutdown.exe ) else if %SystemRoot%\SysWOW64\psshutdown.exe ( %SystemRoot%\SysWOW64\psshutdown.exe ) else ( echo Error: Can't find psshutdown.exe in system directory of Windows. pause )

一种解决方案是在批处理文件中使用以下代码:

psshutdown.exe

此批处理代码独立于将Qt应用程序编译为32位和64位Windows的x64或x86应用程序,并独立于之前复制的系统目录System32

第一个 IF 条件适用于32位Windows上的32位应用程序,64位Windows上只有System32和64位应用程序,64位{{1} }和32位SysWOW64

第二个 IF 条件适用于64位Windows上的32位应用程序,用于访问64位System32

第三个 IF 条件适用于64位Windows上的64位应用程序,用于访问32位SysWOW64

另一个解决方案是将文件psshutdown.exe与64位文件管理器(如Windows资源管理器)一起复制到两个目录

%SystemRoot%\System32
%SystemRoot%\SysWOW64