高見知英の技術ログ

技術関係のログをQiitaから移行してきました。プログラミングのほか、使っているアプリの細かい仕様についてなど書いていきます。

Lazarusプログラムからショートカットを作る

このブログはLazarus(FreePascal)アドベントカレンダー6日目の記事です。

qiita.com

プログラムのショートカットファイル(*.Ink)を作るには、ほかの言語と同様にCOMオブジェクトのShellLinkオブジェクトを使用します。

詳細については公式Wikiを参照。

wiki.lazarus.freepascal.org

ここのミソは二つ

  • windows, shlobj, ActiveX, ComObj;の四つをusesに加えること。
  • IPersistFile.Save()の引数にはWideString型の変数を使うこと*1

なにやらReleaseしてないのが本能的に気になりますが、Releaseメソッドを呼ぼうとするとViolationErrorが発生しますのでとりあえずこのままで。

なお、このコードではWindows APISHGetSpecialFolderLocationを使っていますが、現在のLazarusではLazFileUtilsSHGetFolderPathUTF8というメソッドがあるのでそれを使ってもOK(引数のCSIDL値についてはshlobjユニットに定義されています)。

function Register4StartupClick(): Boolean;
var
  path: WideString;
  ISlink: IShellLink;
  IPFile: IPersistFile;
begin
  path := WideString(SHGetFolderPathUTF8(CSIDL_STARTUP) + 'AppName.lnk');
  if FileExists(path) then
  begin
    Result:= DeleteFile(path);
  end
  else
  begin
    ISlink:=CreateComObject(CLSID_ShellLink) as IShellLink;
    IPFile:= ISlink as IPersistFile;
    ISlink.SetPath(PChar(Application.ExeName));
    ISlink.SetWorkingDirectory(PChar(ExtractFileDir(Application.ExeName)));
    Result:= Succeeded(IPFile.Save(PWChar(path), False));
  end;
end;

スタートアップフォルダに自アプリのショートカットを作成したり削除したりします。

*1:String型ではダメです。どうせPWCharにキャストしてるから問題ないだろーと思ったらそんなことなかった