Как я могу получить имя программы, связанной с расширением файла с помощью Delphi?

StackOverflow https://stackoverflow.com/questions/2577213

Вопрос

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

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

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

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

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

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


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

Похоже, моя вера в то, что имя исполняемого файла не в реестре в конце концов. И после того, как он широко смотрите на API Windows, который даст название, я не мог найти его.

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

Это было полезно?

Решение

Шаг 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 'Anwser к этому вопросу :-)

Шаг 2

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

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

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

Другие советы

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

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

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

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;

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

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

Но я не ищу дружеское имя типа файла.

AssocqueryString возвращает не только дружеское имя для типа файла (Assocrtstr_friendlydocname.), но также может вернуть имя исполняемого файла для открытия файла (ASSOCTR_EXECUTAL) - Это то, что вам нужно.

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

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

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

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

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

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

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

Клавиша имеет входное «приложение», содержащее имя приложения (например, «Soffice.exe»). Это коррелирует к клавише Applcication в HK_CR, например HK_CR\Applications\soffice.exe\

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top