記事カテゴリ

ユーザー機能


 2023年1月30日(月) 10:49 JST

[Delphi] ショートカット作成&情報取得

  • 投稿者:
  • 表示回数
    6,265

客先でショートカットの内容を判断して書き換える必要に迫られまして・・・
同じようなアプリを置き換えるときに探してショートカットも置き換えてねと…
よく考えたらExcelからOpenOfficeに変えてもExcelにドキュメントを引数で渡すようなショートカットでなく、素直にドキュメントへのショートカットを作っておけば対応できるアプリが普通に対応してくれるんですけどね。

と愚痴っても仕方がないので、まずは一般的なショートカットの作成方法

uses に ActiveX, ComObj, ShlObj を追加する必要があるので忘れず追加!

/// ショートカットの作成
/// ショートカットのファイル名
/// コマンドライン文字列(ファイル名)
/// コマンドライン文字列(引数)
/// 作業場所文字列(引数)
/// 説明文字列
function CreateShortCut(const ShortcutPath: String;
                        const ExecFilePath: String;
                        const Params: String;
                        const WorkingDir: String = '';
                        const Description: String = ''): Boolean;
var
  ShellLink: IShellLink;
  PersistFile: IPersistFile;
{$IFDEF Unicode}
  FileName: String;
{$ELSE}
  FileName: WideString;
{$ENDIF}
begin
  // Create shell link object
  // Get IShellLink/IPersistent inferface
  ShellLink := CreateComObject(CLSID_ShellLink) as IShellLink;
  PersistFile := ShellLink as IPersistFile;
  // Set path to shell link 
  ShellLink.SetPath(PChar(ExecFilePath));

  // Set arguments to shell link
  ShellLink.SetArguments(PChar(Params));

  // Set description string
  ShellLink.SetDescription(PChar(Description));

  // Set working directory
  ShellLink.SetWorkingDirectory(PChar(WorkingDir));

  // Set location (path and index) of the icon
  ShellLink.SetIconLocation(PChar(ExecFilePath), 0);

  // Save to file
  FileName := ShortcutPath;
{$IFDEF Unicode}  
  Result := Succeeded(PersistFile.Save(PChar(FileName), True));
{$ELSE}
  Result := Succeeded(PersistFile.Save(PWChar(FileName), True));
{$ENDIF}
end;

ショートカットの情報取得方法

ShellLink.Resolveが結構くせ者で、SLR_ANY_MATCHにせっていしてリンク先がないショートカットだと検索してくれたりする...
システムで処理する際には、SLR_NO_UIでダイアログを出さないようにして書き換えると便利じゃないかな?

type
  TIconLocation = packed record
    Path: string;
    Number: integer;
  end;
  TLinkFileInfo = packed record
    FileName: string; // リンクしているファイル名
    WorkDir: string; // 作業ディレクトリ
    Arguments: string; // コマンドライン引数
    Hotkey: Word; // 設定されているホットキー
    ShowCmd: Integer; // 実行時の表示状態
    Icon: TIconLocation;
  end;

/// ショートカットの情報取得
/// ショートカットのファイル名
/// ショートカット情報構造体
function GetInfofromLinkFile(LinkFilename: string): TLinkFileInfo;
var
  ShellLink: IShellLink;
  PersistFile: IPersistFile;
  WFilename: WideString;
  Win32FindData: TWin32FindData;
  S, Work, Arg: string;
  Hot: Word;
  Cmd: Integer;
  sIconPath: WideString;
  nIconPath: integer;
  nIcon: integer;
begin
  if LowerCase(ExtractFileExt(LinkFilename)) <> '.lnk' then
    Exit;

  ShellLink := CreateComObject(CLSID_ShellLink) as IShellLink;
  PersistFile := ShellLink as IPersistFile;

  // Unicodeにキャスト
  WFilename := LinkFilename;

  if Succeeded(PersistFile.Load(PWChar(WFilename), STGM_READ)) then
  begin
    ShellLink.Resolve(0, SLR_NO_UI);

    SetLength(S, MAX_PATH);
    SetLength(Work, MAX_PATH);
    SetLength(Arg, MAX_PATH);
    SetLength(sIconPath, MAX_PATH);
    nIconPath := MAX_PATH;
    // ショートカットファイルの参照先を取得
    ShellLink.GetPath(PChar(S), MAX_PATH, Win32FindData, SLGP_UNCPRIORITy);
    // 作業ディレクトリを取得
    ShellLink.GetWorkingDirectory(PChar(Work), MAX_PATH);
    // コマンドライン引数を取得
    ShellLink.GetArguments(PChar(Arg), MAX_PATH);
    // ホットキーを取得
    ShellLink.GetHotkey(Hot);
    // 実行時の表示状態を取得
    ShellLink.GetShowCmd(Cmd);
    // アイコンの状態を取得
    ShellLink.GetIconLocation(PWideChar(sIconPath), MAX_PATH, nIcon);

    // 関数の戻り値にセット
    with Result do
    begin
      FileName := S;
      WorkDir := Work;
      Arguments := Arg;
      Hotkey := Hot;
      ShowCmd := Cmd;
      Icon.Path := sIconPath;
      Icon.Number := nIcon;
    end;
  end;
end;

トラックバック

このエントリのトラックバックURL:
https://www.blackcat.xyz/trackback.php/ProgramingFAQ_del0073

以下のコメントは、その投稿者が所有するものでサイト管理者はコメントに関する責任を負いません。