我怎样才能获得该计划的使用Delphi的文件扩展名关联的名称?
-
24-09-2019 - |
题
我需要得到目前与当前用户文件扩展名关联的程序的名称。如果您在文件上单击鼠标右键,选择属性,然后我需要的是对的“打开与”行权的程序名。
e.g。对于是“.xls”,我希望能够得到答案‘Microsoft Office Excel中’,或任何程序的用户作为其默认程序打开.xls文件。
我已经确定了它不是那么容易,因为刚刚进入HKEY_CLASSES_ROOT和采摘它,因为它也可以在HKEY_LOCAL_MACHINE或HKEY_CURRENT_USER或HKEY_USERS指定。
也许所有我需要知道的是Windows使用的啄食顺序,确定这一点,怎么到每个位置。当然,Windows API调用这样做将是理想的。
这是一个类似的问题: 如何获得图标,并用Delphi从文件扩展名的描述?但这个问题只回答如何得到延伸和的描述相关联的程序的图标。我不能找到一种方法来扩展也得到了相关程序的名称。
我使用德尔福2009年,需要一个解决方案,在Windows XP,Vista和Windows 7。
工作感谢大家的答案。
看来我的信念,可执行文件的名称不是在注册表毕竟。并广泛四处寻找一个Windows API,会给名之后,我找不到一个。
我觉得那么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类,你可以通过谷歌找到,例如这里
var VersionInfo: TVersionInfo;
VersionInfo := TVersionInfo.Create('PathToExe\name.exe');
s := VersionInfo.KeyValue['Description'];
但是,你必须要知道,某些程序使用说明关键,因此(如RAD Studio企业本身或MS Excel),而其他人使用的产品名称关键...
其他提示
不要去注册表时,有专门做你所需要的API函数洞穴探险。
在你的情况,你想 AssocQueryString
。你可以给它的文件扩展名,它会告诉你该程序注册用于处理该扩展名(AssocStr_Executable
)。如果你在的运行的该程序打开一个文档,然后你真正想要的命令字符串,而不是仅仅可执行规划; AssocQueryString
可以给你,太(AssocStr_Command
)。它也可以告诉你的文档类型像什么显示在Windows资源管理器,如“文本文档”或“Zip文件”(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的和Rob肯尼迪的回答结合起来。
取罗布肯尼迪的答案,并采取步骤2,从MEF的答案。读取注册表并不能直接做的好事,所以你应该扔掉他的第1部分。
但我不是要查找的文件类型的友好名称。
AssocQueryString返回不仅友好用于文件类型名称( ASSOCSTR_FRIENDLYDOCNAME ),而且它可以返回的可执行文件名称打开文件(的 ASSOCSTR_EXECUTABLE ) - 这是你所需要的。
。甚至不止于此:我不知道,但可能的 ASSOCSTR_FRIENDLYAPPNAME 将满足您的需求。在这种情况下,你可能只使用罗伯肯尼迪的答案。
直接读取注册表的问题是,它可能会返回错误信息。这是因为你读的系统设置 - 这是申请注册的。但用户可以覆盖。例如,他可以右击.xls和选择“打开方式” - >“其他应用程序。” - > “OpenOffice的” - > “使用这个应用程序总是”。对于.xls的类型注册信息,也不会改变(用户首选项保存在单独的地方,所以应用程序不能惹他们),所以你的代码(直接读取注册表)将继续生产“MS Excel的”,即使当用户文件上双击 - OpenOffice的将被启动
如何对这篇文章在这里:确定相关应用
在Excel的具体情况,你会发现HKEY_CLASSES_ROOT下的.xls
扩展 - 该条目的默认值是Excel.Sheet.8
当你去寻找再次在HKEY_CLASSES_ROOT Excel.Sheet.8
,你会发现有Microsoft Office Excel 97-2003 Worksheet
的默认值的条目 - 这可能是尽善尽美。
如果用户说“使用这个应用程序总是”为.xls的档案存储在信息IST
HK_CU\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.xls
在密钥具有条目“应用程序”包含应用程序名称(例如,“soffice.exe”)。它相关的HK_CR,例如一个Applcication关键HK_CR\Applications\soffice.exe\