Как я могу получить название программы, связанной с расширением файла, используя Delphi? - PullRequest
9 голосов
/ 05 апреля 2010

Мне нужно получить имя программы, связанной с расширением файла для текущего пользователя. Если вы щелкнете правой кнопкой мыши по файлу и выберете свойства, тогда мне нужно имя программы, которое находится справа от строки «Opens with».

например. Для ".xls" я хочу получить ответ "Microsoft Office Excel" или любую другую программу, которую пользователь использует в качестве программы по умолчанию для открытия файлов .xls.

Я решил, что это не так просто, как просто зайти в HKEY_CLASSES_ROOT и выбрать его, поскольку он также может быть указан в HKEY_LOCAL_MACHINE или HKEY_CURRENT_USER или HKEY_USERS.

Может быть, все, что мне нужно знать, - это порядок размещения, используемый Windows, чтобы определить это и как добраться до каждого из местоположений. Конечно, для этого был бы идеальным вызов Windows API.

Этот вопрос похож на: Как получить значок и описание из расширения файла с помощью Delphi? , но на этот вопрос ответили только как получить описание расширения и значок соответствующей программы. Я не мог найти способ расширить это, чтобы также получить имя связанной программы.

Я использую Delphi 2009 и мне нужно решение, которое работает на Windows XP, Vista и 7.


Спасибо всем за ответы.

Мне кажется, что имя исполняемого файла в конце концов отсутствует в реестре. И после тщательного поиска Windows API, который даст имя, я не смог найти его.

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

Ответы [ 6 ]

11 голосов
/ 06 апреля 2010

Не путайтесь в реестре, когда есть функции API, разработанные для того, что вам нужно.

В вашем случае вы хотите AssocQueryString. Вы можете дать ему расширение имени файла, и оно сообщит вашей программе, зарегистрированной для обработки этого расширения (AssocStr_Executable). Если вы планируете запустить эту программу для открытия документа, тогда вам действительно понадобится командная строка, а не просто исполняемый файл; AssocQueryString тоже может вам это дать (AssocStr_Command). Он также может указать тип документа, например, отображаемый в проводнике Windows, например «Текстовый документ» или «Zip-архив» (AssocStr_FriendlyDocName).

Эта функция API является оболочкой для интерфейса IQueryAssociations. Если вы ищете программы из разных типов файлов или множества строк, связанных с одним типом, вы можете создать экземпляр этого интерфейса и использовать его повторно, а не вызывать функцию API снова и снова.

4 голосов
/ 12 апреля 2010

Я думаю, что вам нужно объединить ответы Меф и Роба Кеннеди.

Возьмите ответ Роба Кеннеди и сделайте шаг 2 из ответа Мефа. Чтение реестра напрямую не очень хорошая вещь, поэтому вы должны выбросить его часть 1.

Но я не ищу понятное имя типа файла.

AssocQueryString возвращает не только понятное имя для типа файла ( ASSOCSTR_FRIENDLYDOCNAME ), но также может возвращать имя исполняемого файла для открытия файла ( ASSOCSTR_EXECUTABLE ) - это то, что вам нужно.

Даже более того: я не уверен, но может быть ASSOCSTR_FRIENDLYAPPNAME будет соответствовать вашим потребностям. В этом случае вы можете использовать только ответ Роба Кеннеди.

Проблема с чтением реестра напрямую заключается в том, что он может возвращать неверную информацию. Это потому, что вы читаете системные настройки - это то, что приложение зарегистрировано. Но пользователь может переопределить это. Например, он может щелкнуть правой кнопкой мыши на .xls и выбрать «Открыть с помощью ...» -> «Другое приложение». -> «OpenOffice» -> «Используйте это приложение всегда». Информация о регистрации для типа .xls не будет изменена (пользовательские настройки сохраняются в отдельном месте, поэтому приложения не могут связываться с ними), поэтому ваш код (который читает реестр напрямую) будет продолжать выдавать «MS Excel», даже если пользователь дважды щелкает файл - запускается OpenOffice.

4 голосов
/ 06 апреля 2010

Delphi поставляется с модулем ShellApi.pas, который используется в приведенном ниже примере кода. Файл должен существовать.

Вот как это использовать:

function MyShellFindExecutable(const aFileName: string): string;
var
  Buffer: array[0..WINDOWS.MAX_PATH] of Char;
begin
  Result := '';
  FillChar(Buffer, SizeOf(Buffer), #0);
  if (SHELLAPI.FindExecutable(PChar(aFileName), nil, Buffer) > 32) then
    Result := Buffer;
end;
4 голосов
/ 06 апреля 2010

Шаг 1

Получить исполняемый файл, который назначен расширению файла, например, с помощью следующей функции:

uses Registry, Windows, SysUtils;

function GetAssociation(const DocFileName: string): string;
var
  FileClass: string;
  Reg: TRegistry;
begin
  Result := '';
  Reg := TRegistry.Create(KEY_EXECUTE);
  Reg.RootKey := HKEY_CLASSES_ROOT;
  FileClass := '';
  if Reg.OpenKeyReadOnly(ExtractFileExt(DocFileName)) then
  begin
    FileClass := Reg.ReadString('');
    Reg.CloseKey;
  end;
  if FileClass <> '' then begin
    if Reg.OpenKeyReadOnly(FileClass + '\Shell\Open\Command') then
    begin
      Result := Reg.ReadString('');
      Reg.CloseKey;
    end;
  end;
  Reg.Free;
end;

(см. здесь или ответ marc_s на этот вопрос: -)

Шаг 2

Теперь вы можете считать название программы из информации о версии этого исполняемого файла! Самый простой способ - использовать класс TVersionInfo, который вы можете найти через Google, например, здесь .

var VersionInfo: TVersionInfo;  
VersionInfo := TVersionInfo.Create('PathToExe\name.exe');  
s := VersionInfo.KeyValue['Description'];

Однако вы должны знать, что некоторые программы используют ключ описания (например, сама RAD Studio или MS Excel), в то время как другие используют ключ имени продукта ...

3 голосов
/ 05 апреля 2010

Как насчет этой статьи здесь: Определение связанного приложения

В конкретном случае Excel, вы найдете расширение .xls в HKEY_CLASSES_ROOT - значение по умолчанию для этой записи Excel.Sheet.8.

Когда вы снова выполните поиск Excel.Sheet.8 в HKEY_CLASSES_ROOT, вы найдете запись со значением по умолчанию Microsoft Office Excel 97-2003 Worksheet - это, вероятно, так же хорошо, как и сейчас.

0 голосов
/ 30 июля 2010

Если пользователь говорит «используйте это приложение всегда» для .xls-файлов, информация сохраняется в

HK_CU\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.xls

Ключ имеет запись «Приложение», содержащую имя приложения (например, «soffice.exe»). Это связано с ключом приложения в HK_CR, например, HK_CR\Applications\soffice.exe\

...