Как я могу получить имя программы, связанной с расширением файла с помощью Delphi?
-
24-09-2019 - |
Вопрос
Мне нужно получить имя программы в настоящее время, связанной с расширением файла для текущего пользователя. Если вы щелкните правой кнопкой мыши файл и выберите «Свойства», то то, что мне нужно, это имя программы, которое находится справа от «Открывается с» линией.
Например, для «.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\