我想在 Qt 應用程式中彈出可移動 USB 磁盤,并且正在使用 Microsoft 的一個名為Sync (下載) 的工具,用法是sync.exe -e [E:]
所以我從 Qt 運行這個工具,代碼如下:
QString ejectToolPath = QString("%1/sync.exe").arg(qApp->applicationDirPath());
QStringList params;
params << "-e" << driveLetter;
QProcess::startDetached(ejectToolPath, params);
運行此代碼后,可移動 USB 磁盤沒有彈出,如果我使用托盤圖示彈出磁盤,它會警告磁盤正在使用中。
但是,如果我使用 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**
});
}
....
uj5u.com熱心網友回復:
我不認為是這種情況,但構建可執行檔案路徑的更好方法是
QString ejectToolPath = QDir(qApp->applicationDirPath()).filePath("sync.exe")
如果 shadowbuild 被禁用,Qt 在檔案夾debug/中構建應用程式,如果啟用,則在檔案夾中構建應用程式,你 100% 確定在應用程式檔案夾中嗎?再次檢查不會有什么壞處。release/build-xxxxsync.exe
qDebug() << QFile(ejectToolPath).exists()
如果它存在,startDetached則只有在sync.exe依賴的庫之一不在 %PATH% 中時才能啟動。
同步是否需要路徑或驅動器號?E:可能被認為是有效路徑,正確的版本是E:\- 帶有強制斜杠。
uj5u.com熱心網友回復:
這是我的問題。當我列舉可移動 USB 磁盤時,我忘記關閉設備句柄。這導致設備在使用中,與Qt無關。謝謝你的幫助!@mugiseyebrows
STORAGE_HOTPLUG_INFO HMStatusBarWidget::getDeviceType(char driveLetter)
{ STORAGE_HOTPLUG_INFO 資訊 = { 0 };
HANDLE hDevice = getDeviceHandle(driveLetter);
if (hDevice == INVALID_HANDLE_VALUE) {
CloseHandle(hDevice);
return Info;
}
DWORD bytesReturned = 0;
DeviceIoControl(hDevice, IOCTL_STORAGE_GET_HOTPLUG_INFO, 0, 0, &Info, sizeof(Info), &bytesReturned, NULL);
CloseHandle(hDevice);
return Info;
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/437676.html
