Я хочу проверить, можно ли успешно «ОТКРЫТЬ» конкретный файл с помощью ShellExecute, поэтому я пытаюсь использовать AssocQueryString, чтобы обнаружить это.

Примере:

DWORD size = 1024;
TCHAR buff[1024];  // fixed size as dirty hack for testing

int err = AssocQueryString(0, ASSOCSTR_EXECUTABLE, ".mxf", NULL ,buff , &size);
openAction->Enabled  = ((err == S_OK) || (err == S_FALSE)) && (size > 0);

Теперь это почти работает. Если есть зарегистрированное приложение, я получаю строку.

Но есть одна загвоздка: в Vista, даже если нет зарегистрированного приложения, он возвращает, что приложение c: \ Windows \ System32 \ shell32.dll связано, что вызывает на 100% бесполезное сообщение «Windows не может открыться. этот файл: Использовать веб-службу, чтобы найти нужную программу?" диалог.

Очевидно, я хочу скрыть эту часть cr * p от конечных пользователей, но простое сравнение возвращаемой строки с константой кажется уродливым, грубым и хрупким способом сделать это.

Кроме того, взлом реестра для полного отключения этого диалогового окна - не лучшая идея.

Какой вариант лучше?

4
Roddy 12 Авг 2009 в 13:15

2 ответа

Лучший ответ

Я всегда использую FindExecutable(), чтобы получить зарегистрированное приложение для данного документа.

6
fhe 12 Авг 2009 в 15:49
Спасибо - работает отлично, и корректно "дает сбой", если ни одно приложение не зарегистрировано. Пинаю себя за то, что не нашел этого ...
 – 
Roddy
12 Авг 2009 в 18:35
Пришлось вернуться к этому из-за проблем с производительностью Samba. Разместил ответ, который сейчас использую, ниже.
 – 
Roddy
1 Июл 2011 в 20:38

Есть другой способ сделать это, используя флаг опции ASSOCF_INIT_IGNOREUNKNOWN с AssocQueryString().

int err = AssocQueryString(ASSOCF_INIT_IGNOREUNKNOWN, ASSOCSTR_EXECUTABLE, ".mxf", NULL ,buff , &size);

У этого есть несколько важных преимуществ перед использованием FindExecutable()

  • Он может работать только с расширением файла, в то время как FindExecutable требует полного пути к существующему файлу указанного типа.
  • Поскольку он не обращается к файлу, это намного быстрее с Samba и другим сетевым хранилищем. Вызов FindExecutable() для одного файла в каталоге, содержащем ~ 3000 файлов, через Samba в моих тестах занимал> 1 секунды.
4
Roddy 1 Июл 2011 в 20:36
1
Я запутался. Изначально вы сказали, что у вас проблема с Vista, а теперь вы говорите, что у вас есть жизнеспособное решение, используя флаг ASSOCF_INIT_IGNOREUNKNOWN, который, согласно MSDN, был представлен в Windows 7. msdn.microsoft.com/en-us/library/windows/desktop/…
 – 
RenniePet
26 Июл 2012 в 05:24
Да, AssocQueryString более надежен, чем FindExecutable (он также не требует существующего файла): visualstudiomagazine.com/articles/2009/10/13/…. Что касается флага ASSOCF_INIT_IGNOREUNKNOWN, если вам нужна поддержка до Win7, мне действительно нравится ваша идея в удаленном ответе об использовании некоторого GUID в качестве расширения для получения обработчика "без ассоциации" (на самом деле это была моя первая мысль, когда я увидел ваш вопрос).
 – 
Ohad Schneider
8 Ноя 2014 в 14:13