How can I get the program name associated with the file extension using Delphi?

I need to get the name of the program that is currently associated with the file extension for the current user. If you right-click on a file and select properties, then I need the name of the program, which is located to the right of the line "Opens with".

eg. For ".xls" I want to get the answer "Microsoft Office Excel" or any other program that the user has as his default program to open .xls files.

I defined it is not so simple as going to HKEY_CLASSES_ROOT and picking it up, since it can also be specified in HKEY_LOCAL_MACHINE or HKEY_CURRENT_USER or HKEY_USERS.

Perhaps all I need to know is the hierarchy order used by Windows to determine this and how to get to each place. Of course, calling the Windows API for this would be ideal.

This is a similar question: How to get the icon and description from a file extension using Delphi? , but this question only answered how to get the description of the extension and the icon of the corresponding program. I could not find a way to extend this to get the name of the related program.

I am using Delphi 2009 and need a solution that works on Windows XP, Vista and 7.


Thank you all for your answers.

Looks like I suppose the executable file name is not in the registry. And, having carefully examined the Windows API, which will give a name, I could not find it.

I think Mef's answer is then the best. To get the name of the executable file from the information included in the executable file of the program.

+7
windows file-type delphi registry file-association
source share
6 answers

Step 1

Get the executable file that is assigned to the file extension, for example, with the following function:

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; 

(see here , or marc_s' anwser for this question :-)

Step 2

Now you can read the program name from the version information of this executable file! The easiest way is to use the TVersionInfo class, which you can find through Google, for example here .

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

However, you should be aware that some programs use this description key (for example, RAD Studio or MS Excel), while others use the product name key ...

+3
source share

Do not use spelunking in the registry when there are API functions designed to do what you need.

In your case, you want an AssocQueryString . You can tell it the file name extension, and it will tell your program registered to handle this extension ( AssocStr_Executable ). If you plan to run this program to open a document, you really need a command line instead of an executable; AssocQueryString can also give you this ( AssocStr_Command ). It can also indicate the type of document, for example, what is displayed in Windows Explorer, for example, “Text Document” or “Mail Archive” ( AssocStr_FriendlyDocName ).

This API function is a wrapper for IQueryAssociations . If you are looking for programs from many file types or many lines associated with one type, you can instantiate this interface and reuse it instead of calling the API function again and again.

+9
source share

Delphi comes with the ShellApi.pas block, which is used in the sample code below. The file must exist.

Here's how to use it:

 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
source share

I think you need to combine the answers of Mef and Rob Kennedy.

Take Rob Kennedy's answer and take step 2 from Mef's answer. Reading the registry directly is not very good, so you should throw away part 1 of it.

But I'm not looking for a friendly file type name.

AssocQueryString not only returns the friendly name for the file type ( ASSOCSTR_FRIENDLYDOCNAME ), but can also return the name of the executable file to open the file ( ASSOCSTR_EXECUTABLE ) - this is what you need.

Even more: I'm not sure, but maybe ASSOCSTR_FRIENDLYAPPNAME will suit your needs. In this case, you can only use Rob Kennedy's answer.

The problem with reading the registry directly is that it can return incorrect information. This is because you are reading system settings - this is because the application is registered. But the user can override this. For example, he can right-click on .xls and select "Open with ..." → "Another application". → "OpenOffice" → "Always use this application." Registration information for the .xls type will not be changed (user settings are stored in a separate place, therefore applications cannot communicate with them), therefore your code (which reads the registry directly) will continue to issue "MS Excel", although when the user double-clicks on the file - OpenOffice will be launched.

+4
source share

How about this article here: Defining a related application

In the specific case of Excel, you will find the .xls extension under HKEY_CLASSES_ROOT - the default value for this entry is Excel.Sheet.8 .

When you search Excel.Sheet.8 in HKEY_CLASSES_ROOT, you will find an entry with the default Microsoft Office Excel 97-2003 Worksheet , which is probably as good as it is.

+3
source share

If the user says "always use this application" for .xls files, the information is stored in

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

The key has an "Application" entry containing the name of the application (for example, "soffice.exe"). It is mapped to the Applcication key in HK_CR, for example. HK_CR\Applications\soffice.exe\

0
source share

All Articles