ShellExecuteEx с SEE_MASK_FLAG_NO_UI в любом случае отображает сообщение

#windows #winapi #windows-10 #shellexecuteex

#Windows #winapi #windows-10 #shellexecuteex

Вопрос:

В моей системе расширение .xyz вообще не зарегистрировано. Итак, когда я дважды щелкаю по файлу .xyz в проводнике, Windows 10 выводит стандартное диалоговое окно «Как вы хотите открыть этот файл», которое ожидается.

Теперь, когда я запускаю этот короткий фрагмент, отображается то же диалоговое окно, что и выше, хотя я поставил SEE_MASK_FLAG_NO_UI флаг в sei.fMask :

   SHELLEXECUTEINFO sei = { 0 };
  sei.cbSize = sizeof(SHELLEXECUTEINFO) ;
  sei.fMask = SEE_MASK_FLAG_NO_UI;
  sei.hwnd = AfxGetMainWnd()->GetSafeHwnd();
  sei.lpVerb = _T("open");
  sei.lpFile = _T("C:\Users\Test\Documents\temp\Temp.xyz");
  sei.lpParameters = NULL;
  sei.lpDirectory = appdir;
  sei.nShow = SW_SHOW;
  ShellExecuteEx(amp;sei); 
  
  • Файл "C:\Users\Test\Documents\temp\Temp.xyz" существует.

  • Тот же код с sei.lpFile указанием на существующий файл .txt открывает его с помощью Notepad, как и ожидалось.

В документации утверждается, что сообщение об ошибке не должно отображаться с SEE_MASK_FLAG_NO_UI .

Итак, что я могу сделать, чтобы ShellExecuteEx не появлялось никаких сообщений, а вместо этого возвращался код ошибки?

Я проверил это только в Windows 10, я не знаю, как это работает в более старых версиях Windows.

Комментарии:

1. Я думаю, это не диалоговое окно с ошибкой, не так ли. Это диалоговое окно, позволяющее пользователю сформировать ассоциацию, чтобы затем оболочка могла попытаться вызвать глагол.

2. @DavidHeffernan, точно, это не сообщение об ошибке. В любом случае я не хочу, чтобы отображался какой-либо пользовательский интерфейс. Возможно, мне следует просто проверить, существует ли ключ «.xyz» в реестре в разделе ShellExecuteEx , и если нет, то все вместе закоротить.

Ответ №1:

Используйте FindExecutable() или AssocQueryString() перед вызовом ShellExecute(). Это позволяет проверить, существует ли связь. SEE_MASK_FLAG_NO_UI предотвращает отображение ошибки, однако эта ситуация не рассматривается как ошибка.

Комментарии:

1. Это не на 100% надежно, даже если эти функции говорят «нет», все равно может быть расширение оболочки. DLL, которая обрабатывает действие по умолчанию при выполнении типа файла.

2. Где вы это нашли?

3. Расширение оболочки. Библиотеки DLL могут динамически определять, являются ли они действием по умолчанию, нет способа узнать, фактически не выполняя их код.

4. @Майкл Андерс прав. Я написал расширение оболочки, которое делает именно это. Оно динамически выполняет действие по умолчанию. Если выполняемый файл имеет определенный заголовок, выполняется мое приложение, в противном случае вместо него выполняется обычное приложение по умолчанию. Смотрите Регистрацию обработчика контекстного меню с помощью динамического глагола относительно использования MayChangeDefaultMenu параметра реестра при регистрации расширения оболочки

5. Хорошо, в этом случае вы ничего не сможете сделать. Предоставленные мной функции могут возвращать ложноотрицательное значение, но никогда ложноположительное, поэтому он никогда не получит неприятное окно «открыть с помощью».