在 Qt 中运行可执行文件失败,在 Windows cmd 中运行成功
我想在 Qt 应用程序中弹出可移动 USB 磁盘,并使用 Microsoft 的一个名为 Sync 的工具(download) ,用法是 sync.exe -e [E:]
所以我从 Qt 运行这个工具,代码如下:
QString ejectToolPath = QString("%1/sync.exe").arg(qApp->applicationDirPath());
QStringList params;
params << "-e" << driveLetter;
QProcess::startDetached(ejectToolPath, params);
运行后这段代码,可移动U盘是未弹出,如果我使用托盘图标弹出磁盘,它会警告磁盘正在使用中。
但是,如果我使用 Windows 资源管理器托盘图标或在 cmd 或 powershell 中运行sync.exe,它就能够弹出该设备。我是否缺少某些内容,或者在 shell 和 Qt 中运行 exe 之间存在差异。
这个问题困扰我好几天了,希望有人能帮忙。
提前致谢!
[2022-03-03更新]
经过测试,我缩小了问题的范围。 我的应用场景是这样的,首先点击QPushButton弹出可移动设备列表,然后选择要弹出的设备,点击菜单项,调用真正的弹出函数。 顺便说一句,设备列表小部件设置了 Qt::Popup 属性。
setWindowFlags(windowFlags() | Qt::FramelessWindowHint | Qt::Popup);
我发现如果我直接调用弹出设备功能,它执行正常,但如果单击具有相同代码的弹出菜单项失败。有什么区别?
成功:
void HMStatusBarWidget::onPluginButtonClick() {
ejectDevice("D:"); // **success**
/*QHash<QString, QString> deviceList;
if (deviceListWidget_ == nullptr) {
deviceListWidget_ = new PopupListWidget(this);
connect(deviceListWidget_, &PopupListWidget::textItemClicked, [=]() {
ejectDevice("D:"); // **fail**
});
}*/
....
失败:
void HMStatusBarWidget::onPluginButtonClick() {
//ejectDevice("D:"); // **success**
QHash<QString, QString> deviceList;
if (deviceListWidget_ == nullptr) {
deviceListWidget_ = new PopupListWidget(this);
connect(deviceListWidget_, &PopupListWidget::textItemClicked, [=]() {
ejectDevice("D:"); // **fail**
});
}
....
I want to eject removable USB disk in Qt application, and was using a tool from Microsoft called Sync(download) , the usage is sync.exe -e [E:]
So I was running this tool from Qt with code below:
QString ejectToolPath = QString("%1/sync.exe").arg(qApp->applicationDirPath());
QStringList params;
params << "-e" << driveLetter;
QProcess::startDetached(ejectToolPath, params);
after running this code, the removable Usb disk was not ejected, and if I use the tray icon to eject the disk, it warns the disk is in use.
But if I use the windows explorer tray icon or run the sync.exe in cmd or powershell, it was able to eject that device.Am I missing something or there is difference between run the exe in shell and in Qt.
This problem has tormented me for days, hope someone can help.
Thanks in advance!
[2022-03-03 update]
After testing, I narrowed down the scope of the problem.
My application scenario is like this, First click the QPushButton to popup the removable device list, then select the device to eject, on click of the menu item, call the real eject function.
By the way, the device list widget is set the Qt::Popup attribute.
setWindowFlags(windowFlags() | Qt::FramelessWindowHint | Qt::Popup);
I found if I directly call eject device function, it performs OK, but if fail on click the popup menu item with the same code. what was the difference?
SUCEESS:
void HMStatusBarWidget::onPluginButtonClick() {
ejectDevice("D:"); // **success**
/*QHash<QString, QString> deviceList;
if (deviceListWidget_ == nullptr) {
deviceListWidget_ = new PopupListWidget(this);
connect(deviceListWidget_, &PopupListWidget::textItemClicked, [=]() {
ejectDevice("D:"); // **fail**
});
}*/
....
FAILURE:
void HMStatusBarWidget::onPluginButtonClick() {
//ejectDevice("D:"); // **success**
QHash<QString, QString> deviceList;
if (deviceListWidget_ == nullptr) {
deviceListWidget_ = new PopupListWidget(this);
connect(deviceListWidget_, &PopupListWidget::textItemClicked, [=]() {
ejectDevice("D:"); // **fail**
});
}
....
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我不认为是这样,但构建可执行文件路径的更好方法是
QStringjectToolPath = QDir(qApp->applicationDirPath()).filePath("sync.exe")
Qt 在
中构建应用程序>debug/
或release/
文件夹(如果 Shadowbuild 被禁用)和build-xxxx
文件夹(如果启用),您是否 100% 确定sync.exe
位于应用程序文件夹中?再次检查不会有什么坏处。qDebug() << QFile(ejectToolPath).exists()
如果存在,则仅当
sync.exe
依赖的库之一不在 %PATH 中时,startDetached
才会启动失败%。同步需要路径或驱动器号吗?
E: 可能被视为无效路径,正确的版本是
E:\
- 带有强制尾部斜杠。I dont think it's the case but better way to build path to executable is
QString ejectToolPath = QDir(qApp->applicationDirPath()).filePath("sync.exe")
Qt builds application in
debug/
orrelease/
folder if shadowbuild is disabled and inbuild-xxxx
folder if enabled, are you 100% suresync.exe
is in application folder? It wont hurt to check again.qDebug() << QFile(ejectToolPath).exists()
If it's there
startDetached
can only fail to start if one of libraries thatsync.exe
depends on is not in %PATH%.Does sync expect path or drive letter?
E:
may be considered as ivalid path, the correct version isE:\
- with mandatory trailing slash.这是我的问题。当我枚举可移动 USB 磁盘时,我忘记关闭设备句柄。这会导致设备正在使用,与Qt无关。
感谢您的帮助! @mugiseebrows
{
STORAGE_HOTPLUG_INFO 信息 = { 0 };
}
It's my problem. When I was enumerating removable usb disks, I forget to close the device handle. This cause the device in use, It has nothing to do with Qt.
Thanks for your help! @mugiseyebrows
{
STORAGE_HOTPLUG_INFO Info = { 0 };
}