windows 如何使用 Delphi 获取与文件扩展名关联的程序名称?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2577213/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How can I get the Name of the Program associated with a file extension using Delphi?
提问by lkessler
I need to get the name of the program currently associated with a file extension for the current user. If you right-click on a file and select properties, then what I need is the program name that is to the right of the "Opens with" line.
我需要获取当前与当前用户的文件扩展名关联的程序的名称。如果您右键单击一个文件并选择属性,那么我需要的是“打开方式”行右侧的程序名称。
e.g. For ".xls", I want to be able to get the answer "Microsoft Office Excel", or whatever program the user has as their default program to open .xls files.
例如,对于“.xls”,我希望能够得到答案“Microsoft Office Excel”,或者用户使用的任何程序作为打开 .xls 文件的默认程序。
I have determined it's not as easy as just going into HKEY_CLASSES_ROOT and picking it out, since it may also be specified in HKEY_LOCAL_MACHINE or HKEY_CURRENT_USER or HKEY_USERS.
我已经确定它不像进入 HKEY_CLASSES_ROOT 并把它挑出来那么容易,因为它也可以在 HKEY_LOCAL_MACHINE 或 HKEY_CURRENT_USER 或 HKEY_USERS 中指定。
Maybe all I need to know is the pecking order used by Windows to determine this and how to get to each of the locations. Of course, a Windows API call to do this would be ideal.
也许我只需要知道 Windows 使用的啄食顺序来确定这一点以及如何到达每个位置。当然,执行此操作的 Windows API 调用将是理想的。
This is a similar question to: How to get icon and description from file extension using Delphi?but that question only answered how to get the description of the extension and the icon of the associated program. I couldn't find a way to extend that to also get the name of the associated program.
这是一个类似的问题: How to get icon and description from file extension using Delphi? 但那个问题只回答了如何获取扩展程序的描述和相关程序的图标。我找不到一种方法来扩展它以获取相关程序的名称。
I'm using Delphi 2009 and need a solution that works on Windows XP, Vista and 7.
我使用的是 Delphi 2009,需要一个适用于 Windows XP、Vista 和 7 的解决方案。
Thank you all for your answers.
谢谢大家的答案。
It appears my belief that the name of the executable is not in the Registry after all. And after looking around extensively for a Windows API that will give the name, I could not find one.
我似乎相信可执行文件的名称毕竟不在注册表中。在广泛地寻找将给出名称的 Windows API 之后,我找不到一个。
I think Mef's answer then is the best. To get the name of the executable from the information included in the program's executable.
我认为 Mef 的答案是最好的。从程序的可执行文件中包含的信息中获取可执行文件的名称。
Followup: I found David Hefferman's answer to "How do I open a file with the default text editor?"gives an excellent solution for opening one program using the default program for a different extension.
跟进:我找到了David Hefferman 对“如何使用默认文本编辑器打开文件?”的回答。为使用不同扩展名的默认程序打开一个程序提供了一个很好的解决方案。
采纳答案by Leo
Step 1
第1步
Get the executable which is assigned to a file extension, for instance 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 to this question :-)
(见这里,或 marc_s 对此问题的回答:-)
Step 2
第2步
Now you can read out the name of the program from the version information of this executable! The easiest way is using the TVersionInfo class you can find via Google, for instance here.
现在你可以从这个可执行文件的版本信息中读出程序的名称了!最简单的方法是使用您可以通过 Google 找到的 TVersionInfo 类,例如这里。
var VersionInfo: TVersionInfo;
VersionInfo := TVersionInfo.Create('PathToExe\name.exe');
s := VersionInfo.KeyValue['Description'];
However, you have to be aware that some programs use the description key therefore (like RAD Studio itself or MS Excel), while others use the product name key...
但是,您必须注意某些程序因此使用描述键(例如 RAD Studio 本身或 MS Excel),而其他程序使用产品名称键...
回答by Rob Kennedy
Don't go spelunking in the registry when there are API functions designed to do what you need.
当有 API 函数可以满足您的需求时,请不要在注册表中进行探索。
In your case, you want AssocQueryString
. You can give it the file-name extension, and it will tell your the program registered to handle that extension (AssocStr_Executable
). If you're planning on runningthat program to open a document, then you'll really want the command string instead of just the executable; AssocQueryString
can give you that, too (AssocStr_Command
). It can also tell you the document type like what's displayed in Windows Explorer, like "Text Document" or "Zip Archive" (AssocStr_FriendlyDocName
).
在你的情况下,你想要AssocQueryString
. 你可以给它文件扩展名,它会告诉你注册的程序来处理这个扩展名 ( AssocStr_Executable
)。如果您打算运行该程序来打开文档,那么您真的需要命令字符串而不仅仅是可执行文件;AssocQueryString
也可以给你(AssocStr_Command
)。它还可以告诉您文档类型,例如 Windows 资源管理器中显示的内容,例如“文本文档”或“Zip 存档”( AssocStr_FriendlyDocName
)。
That API function is a wrapper for the IQueryAssociations
interface. If you're looking for programs from many file types, or lots of strings associated with a single type, you may wish to instantiate that interface and re-use it instead of calling the API function over and over.
该 API 函数是IQueryAssociations
接口的包装器。如果您正在从多种文件类型或与单一类型关联的大量字符串中查找程序,您可能希望实例化该接口并重新使用它,而不是一遍又一遍地调用 API 函数。
回答by RobertFrank
Delphi comes with a unit ShellApi.pas that is used in the sample code below. The file has to exist.
Delphi 带有一个单元 ShellApi.pas,在下面的示例代码中使用。该文件必须存在。
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;
回答by Alex
I think that you need to combine Mef's and Rob Kennedy's answers.
我认为您需要结合 Mef 和 Rob Kennedy 的答案。
Take Rob Kennedy's answer and take step 2 from Mef's answer. Reading registry directly isn't good thing to do, so you should throw away his part 1.
采取 Rob Kennedy 的回答并从 Mef 的回答中进行第 2 步。直接读取注册表不是一件好事,所以你应该扔掉他的第 1 部分。
But I'm not looking for the friendly name of the file type.
但我不是在寻找文件类型的友好名称。
AssocQueryString returns not only friendly name for file type (ASSOCSTR_FRIENDLYDOCNAME), but also it can return the name of executable to open file (ASSOCSTR_EXECUTABLE) - that is what you need.
AssocQueryString 不仅返回文件类型的友好名称(ASSOCSTR_FRIENDLYDOCNAME),而且它还可以返回可执行文件的名称以打开文件(ASSOCSTR_EXECUTABLE) - 这就是您所需要的。
Even more than that: I'm not sure, but may be ASSOCSTR_FRIENDLYAPPNAMEwill match your needs. In that case, you may use only Rob Kennedy's answer.
更重要的是:我不确定,但ASSOCSTR_FRIENDLYAPPNAME可能会满足您的需求。在这种情况下,您只能使用 Rob Kennedy 的答案。
The problem with reading registry directly is that it may return wrong info. That's because you read system settings - that is what application registered. But user may override this. For example, he may right click on .xls and select "Open with..." -> "Other app." -> "OpenOffice" -> "Use this app always". Registration info for .xls type will not be altered (user preferences are saved in separate place, so apps can't mess with them), so your code (which reads registry directly) will continue to produce "MS Excel", even though when user double-clicks on file - OpenOffice will be launched.
直接读取注册表的问题是它可能返回错误的信息。那是因为您阅读了系统设置 - 这就是应用程序注册的内容。但是用户可以覆盖它。例如,他可以右键单击 .xls 并选择“打开方式...”->“其他应用程序”。->“OpenOffice”->“始终使用此应用程序”。.xls 类型的注册信息不会被更改(用户首选项保存在单独的位置,因此应用程序不会与它们混淆),因此您的代码(直接读取注册表)将继续生成“MS Excel”,即使当用户双击文件 - 将启动 OpenOffice。
回答by marc_s
How about this article here: Determining the associated application
这篇文章怎么样:确定关联的应用程序
In the concrete case of Excel, you will find the .xls
extension under HKEY_CLASSES_ROOT - the default value of that entry is Excel.Sheet.8
.
在 Excel 的具体情况下,您会.xls
在 HKEY_CLASSES_ROOT 下找到扩展名 - 该条目的默认值是Excel.Sheet.8
.
When you go search for Excel.Sheet.8
again in HKEY_CLASSES_ROOT, you'll find an entry with a default value of Microsoft Office Excel 97-2003 Worksheet
- that's probably as good as it gets.
当您Excel.Sheet.8
在 HKEY_CLASSES_ROOT 中再次搜索时,您会找到一个默认值为 的条目Microsoft Office Excel 97-2003 Worksheet
- 这可能与它得到的一样好。
回答by Tontyna
If the user says "use this app always" for .xls-files the info ist stored in
如果用户对 .xls 文件说“始终使用此应用程序”,则信息将存储在
HK_CU\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.xls
The key has an entry "Application" containing the Application name (e.g. "soffice.exe"). It's correlated to an Applcication key in HK_CR, e.g. HK_CR\Applications\soffice.exe\
该键有一个条目“Application”,其中包含应用程序名称(例如“soffice.exe”)。它与 HK_CR 中的 Applcication 键相关,例如HK_CR\Applications\soffice.exe\