我需要得到目前与当前用户文件扩展名关联的程序的名称。如果您在文件上单击鼠标右键,选择属性,然后我需要的是对的“打开与”行权的程序名。

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\

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top