Russian Qt Forum

Qt => Общие вопросы => Тема начата: hank от Март 03, 2011, 13:16



Название: Запуск проводника Windows
Отправлено: hank от Март 03, 2011, 13:16
Для запуска виндосовского проводника испольщую следующий код:
Код
C++ (Qt)
QString FileName = QFileDialog::getExistingDirectory(this,"Choose directory","/",QFileDialog::ShowDirsOnly
                                                | QFileDialog::DontResolveSymlinks);
 
QUrl url = QUrl::QUrl("file:///"+FileName);
 
QDesktopServices::openUrl(url);

В итоге получаю, что на функции openUrl приложение подвисает минуты на три и только потом открывает проводник. При этом если я продолжаю выбирать другие папки, они открываются с нормальной скоростью.
Что я делаю не так?


Название: Re: Запуск проводника Windows
Отправлено: Пантер от Март 03, 2011, 13:19
1. Используй QUrl QUrl::fromLocalFile ( const QString & localFile ) [static].
2. Виснет именно на QDesktopServices::openUrl(url);?
3. А так проводник быстро запускается?
4. Путь не сетевой, случайно?


Название: Re: Запуск проводника Windows
Отправлено: hank от Март 03, 2011, 13:53
1. Быстрее не стало.
2. Да.
3. Да.
4. Нет, путь не сетевой.

Последующие вызовы openUrl из того же приложения выполняются быстро.


Название: Re: Запуск проводника Windows
Отправлено: merke от Март 03, 2011, 14:57
У меня тоже самое было, когда я открывал ссылку на сайт в браузере.
Решения не нашел, наверное так у всех и это - БАГ детектед


Название: Re: Запуск проводника Windows
Отправлено: GreatSnake от Март 03, 2011, 15:28
Судя по коду qdesktopservices_win.cpp:
Код
C++ (Qt)
static bool openDocument(const QUrl &file)
{
if (!file.isValid())
return false;
QString filePath = file.toLocalFile();
if (filePath.isEmpty())
filePath = file.toString();
quintptr returnValue = (quintptr)ShellExecute(0, 0, (wchar_t*)filePath.utf16(), 0, 0, SW_SHOWNORMAL);
return (returnValue > 32); //ShellExecute returns a value greater than 32 if successful
}
 
Qt и висеть-то негде. Надо WinAPI::ShellExecute() в простом тесте проверить с таким url.


ShellExecute Function Remarks (http://msdn.microsoft.com/en-us/library/bb762153%28v=vs.85%29.aspx):
Цитировать
Because ShellExecute can delegate execution to Shell extensions (data sources, context menu handlers, verb implementations) that are activated using Component Object Model (COM), COM should be initialized before ShellExecute is called. Some Shell extensions require the COM single-threaded apartment (STA) type. In that case, COM should be initialized as shown here:

CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE)

There are certainly instances where ShellExecute does not use one of these types of Shell extension and those instances would not require COM to be initialized at all. Nonetheless, it is good practice to always initalize COM before using this function.
Может в этом дело?