代码之家  ›  专栏  ›  技术社区  ›  lkessler

如何使用delphi获取与文件扩展名关联的程序名?

  •  9
  • lkessler  · 技术社区  · 15 年前

    我需要获取当前用户当前与文件扩展名关联的程序的名称。如果右键单击文件并选择属性,则我需要的是“打开方式”行右侧的程序名。

    例如,对于“.xls”,我希望能够得到答案“MicrosoftOfficeExcel”,或者用户作为默认程序打开.xls文件的任何程序。

    我已经确定,这并不像只进入hkey_classes_root并选择它那么容易,因为它也可能在hkey_local_machine或hkey_current_user或hkey_user s中指定。

    也许我需要知道的只是windows用来确定这个和如何到达每个位置的啄食顺序。当然,一个windows api调用来实现这一点是理想的。

    这个问题类似于: How to get icon and description from file extension using Delphi? 但这个问题只回答了如何获得扩展的描述和相关程序的图标。我找不到一种方法来扩展它来获得相关程序的名称。

    我正在使用Delphi2009,需要一个可以在WindowsXP、Vista和7上运行的解决方案。


    谢谢大家的回答。

    看来我认为可执行文件的名称根本不在注册表中。在到处寻找一个能给出名字的windows api之后,我找不到。

    我认为那时候mef的回答是最好的。从程序可执行文件中包含的信息获取可执行文件的名称。

    6 回复  |  直到 11 年前
        1
  •  4
  •   Leo user370469    15 年前

    步骤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;
    

    (见 here ,或者marc_'s anwser来回答这个问题:-)

    步骤2

    现在您可以从这个可执行文件的版本信息中读出程序的名称!最简单的方法是使用你可以通过google找到的tversioninfo类,例如 here .

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

    但是,您必须注意,有些程序因此使用描述码(如rad studio本身或ms-excel),而其他程序则使用产品名称键…

        2
  •  11
  •   Rob Kennedy    15 年前

    当有一些api函数被设计来满足您的需要时,不要在注册表中进行spelunging。

    在你的情况下,你想要 AssocQueryString . 你可以给它文件扩展名,它会告诉你注册的程序来处理这个扩展名( AssocStr_Executable )如果你打算 运行 那个程序打开一个文档,然后你就真的需要命令字符串而不仅仅是可执行文件; 协会 也能给你这个( AssocStr_Command )它还可以告诉您文档类型,如在windows资源管理器中显示的内容,如“文本文档”或“压缩存档”( AssocStr_FriendlyDocName )

    该api函数是 IQueryAssociations 接口。如果您正在查找来自多个文件类型或与单个类型相关联的多个字符串的程序,则可能希望实例化该接口并重新使用它,而不是一遍又一遍地调用api函数。

        3
  •  4
  •   RobertFrank Picarus    15 年前

    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;
    
        4
  •  4
  •   Alex    15 年前

    我认为你需要把mef和rob kennedy的答案结合起来。

    接受罗伯·肯尼迪的回答,从梅夫的回答中采取第二步。直接阅读注册表不是件好事,所以你应该扔掉他的第1部分。

    但我不是在寻找文件类型的友好名称。

    assocquerystring不仅返回文件类型的友好名称( ASSOCSTR_FRIENDLYDOCNAME ,但也可以返回可执行文件的名称以打开文件( ASSOCSTR_EXECUTABLE )-这就是你需要的。

    更重要的是:我不确定,但可能是 ASSOCSTR_FRIENDLYAPPNAME 会满足你的需要。在这种情况下,你可以只用罗伯·肯尼迪的答案。

    直接读取注册表的问题是它可能返回错误的信息。那是因为你读了系统设置-这就是应用程序注册的内容。但用户可能会忽略这一点。例如,他可以右键单击.xls并选择“打开方式…”->“其他应用。”->“OpenOffice”->“始终使用此应用”。不会更改.xls类型的注册信息(用户首选项保存在单独的位置,因此应用程序不能与之混淆),因此您的代码(直接读取注册表)将继续生成“MS Excel”,即使用户双击文件时也会启动OpenOffice。

        5
  •  3
  •   marc_s    15 年前

    这篇文章怎么样: Determining the associated application

    在excel的具体例子中,您将发现 .xls hkey_classes_root下的扩展名-该项的默认值为 Excel.Sheet.8 .

    当你去寻找 excel.sheet.8表格 同样在hkey_classes_root中,您会发现一个默认值为 Microsoft Office Excel 97-2003 Worksheet -那可能是最好的了。

        6
  •  0
  •   Tontyna    15 年前

    如果用户对存储在

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

    密钥有一个包含应用程序名称的条目“application”(例如“soffice.exe”)。它与香港的应用程序密钥相关,例如 HK_CR\Applications\soffice.exe\