如何获取Windows控制面板的FileName和目录?

时间:2018-01-20 21:27:37

标签: delphi delphi-10.1-berlin control-panel

在Delphi中,创建一个VCL表单应用程序。如果您使用的是64位Windows,请使用64位Windows平台。

使用以下代码:

unit Unit1;

interface

uses
  CodeSiteLogging,
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.ComCtrls;

type
  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
  private
    procedure GetControlPanelItems;
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

uses
  Winapi.ShlObj, Winapi.ShellAPI, System.Win.ComObj;

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
  GetControlPanelItems;
end;

procedure TForm1.GetControlPanelItems;
var
  psfDeskTop: IShellFolder;
  psfControl: IShellFolder;
  pidControl: PITEMIDLIST;
  pidChild: PITEMIDLIST;
  pidAbsolute: PItemIdList;
  pEnumList: IEnumIDList;
  celtFetched: ULONG;
  FileInfo: SHFILEINFOW;
  ShExeInfo: SHELLEXECUTEINFO;
begin
  OleCheck(SHGetDesktopFolder(psfDeskTop));
  OleCheck(SHGetSpecialFolderLocation(0, CSIDL_CONTROLS, pidControl));
  OleCheck(psfDeskTop.BindToObject(pidControl, nil, IID_IShellFolder, psfControl));
  OleCheck(psfControl.EnumObjects(0, SHCONTF_NONFOLDERS or SHCONTF_INCLUDEHIDDEN or SHCONTF_FOLDERS, pEnumList));

  while pEnumList.Next(1, pidChild, celtFetched) = 0 do
  begin
    pidAbsolute := ILCombine(pidControl, pidChild);
    SHGetFileInfo(LPCTSTR(pidAbsolute), 0, FileInfo, SizeOf(FileInfo), SHGFI_PIDL or SHGFI_DISPLAYNAME or SHGFI_TYPENAME);

    CodeSite.Send('TForm1.GetControlPanelItems: szDisplayName', FileInfo.szDisplayName);

    // Exe-Info:
    ZeroMemory(@ShExeInfo, SizeOf(ShExeInfo));
    ShExeInfo.cbSize := SizeOf(ShExeInfo);
    ShExeInfo.lpVerb := 'Open';
    // control panel item's PIDL:
    ShExeInfo.lpIDList := pidAbsolute;
    ShExeInfo.nShow := SW_SHOWNORMAL;
    ShExeInfo.fMask := SEE_MASK_IDLIST;
    //ShExeInfo.lpFile := ???
    //ShExeInfo.lpDirectory := ???

    CodeSite.Send('TForm1.GetControlPanelItems: ShExeInfo.lpFile', ShExeInfo.lpFile);
    CodeSite.Send('TForm1.GetControlPanelItems: ShExeInfo.lpDirectory', ShExeInfo.lpDirectory);
  end;
end;

end.

这会让我看到控制面板的显示名称

但是我怎样才能获得文件路径? (ShExeInfo.lpDirectory,ShExeInfo.lpFile)

1 个答案:

答案 0 :(得分:1)

正如其他人所提到的,尝试获取某个applet二进制文件的文件名可能毫无价值,因为在一个二进制文件中可以实现多个applet。对于您的整体任务,放入评论,创建shell快捷方式链接,只需使用您在循环中知道的绝对ITEMIDLIST,并通过IShellLink方法将其设置为创建的SetIDList对象