我有一个带有按钮的小型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
在将echo %PATH%
添加到.bat时,两个版本的路径似乎都打印好了。知道什么可能是错的吗?
这已在Qt 5.5和5.7,调试和发布模式下在两台不同的计算机上进行了测试。
如果需要,我可以提供完整的源代码,但它只是一个带有添加按钮的Qt Widgets Aplication,使用Qt Creator中的模板。
答案 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