检查Inno安装程序中是否存在快捷方式

在我的Inno Setup安装程序中,我需要确保某个文件的快捷方式存在于文件夹中。 快捷方式的名称是任意的,不在我的控制之下。 我只知道它需要指向哪个文件。 如果缺less快捷方式,我需要生成快捷方式。 如果已经存在,则不能再次创build。

我想这是在某种程度上遍历相关文件夹中的所有快捷方式文件,并检查他们指向哪个文件。 在对共享快捷方式/图标的回答的评论中,提到了一个IShellLink接口,但是我不知道如何在Code部分使其可用。 ( Uses ShlObj;不被识别)

有人有build议我怎么能解决这个问题?

Solutions Collecting From Web of "检查Inno安装程序中是否存在快捷方式"

基于

  • Inno Setup CodeAutomation2.iss官方示例和
  • @TLama删除回答如何获取InnoSetup的快捷方式目标路径 。

需要Unicode版本的Inno Setup。

 const MAX_PATH = 260; STGM_READ = $00000000; SLGP_SHORTPATH = $1; SLGP_RAWPATH = $4; SLGP_RELATIVEPRIORITY = $8; CLSID_ShellLink = '{00021401-0000-0000-C000-000000000046}'; type TWin32FindDataW = record dwFileAttributes: DWORD; ftCreationTime: TFileTime; ftLastAccessTime: TFileTime; ftLastWriteTime: TFileTime; nFileSizeHigh: DWORD; nFileSizeLow: DWORD; dwReserved0: DWORD; dwReserved1: DWORD; cFileName: array[0..MAX_PATH-1] of Char; cAlternateFileName: array[0..13] of Char; end; IShellLinkW = interface(IUnknown) '{000214F9-0000-0000-C000-000000000046}' function GetPath(pszFile: string; cchMaxPath: Integer; var FindData: TWin32FindDataW; fFlags: DWORD): HRESULT; procedure Dummy2; procedure Dummy3; function GetDescription(pszName: string; cchMaxName: Integer): HRESULT; function SetDescription(pszName: string): HRESULT; function GetWorkingDirectory(pszDir: string; cchMaxPath: Integer): HRESULT; function SetWorkingDirectory(pszDir: string): HRESULT; function GetArguments(pszArgs: string; cchMaxPath: Integer): HRESULT; function SetArguments(pszArgs: string): HRESULT; function GetHotkey(var pwHotkey: Word): HRESULT; function SetHotkey(wHotkey: Word): HRESULT; function GetShowCmd(out piShowCmd: Integer): HRESULT; function SetShowCmd(iShowCmd: Integer): HRESULT; function GetIconLocation(pszIconPath: string; cchIconPath: Integer; out piIcon: Integer): HRESULT; function SetIconLocation(pszIconPath: string; iIcon: Integer): HRESULT; function SetRelativePath(pszPathRel: string; dwReserved: DWORD): HRESULT; function Resolve(Wnd: HWND; fFlags: DWORD): HRESULT; function SetPath(pszFile: string): HRESULT; end; IPersist = interface(IUnknown) '{0000010C-0000-0000-C000-000000000046}' function GetClassID(var classID: TGUID): HRESULT; end; IPersistFile = interface(IPersist) '{0000010B-0000-0000-C000-000000000046}' function IsDirty: HRESULT; function Load(pszFileName: string; dwMode: Longint): HRESULT; function Save(pszFileName: string; fRemember: BOOL): HRESULT; function SaveCompleted(pszFileName: string): HRESULT; function GetCurFile(out pszFileName: string): HRESULT; end; function GetLinkFileTarget(const FileName: string): string; var FindData: TWin32FindDataW; ComObject: IUnknown; ShellLink: IShellLinkW; PersistFile: IPersistFile; begin ComObject := CreateComObject(StringToGuid(CLSID_ShellLink)); PersistFile := IPersistFile(ComObject); OleCheck(PersistFile.Load(FileName, STGM_READ)); ShellLink := IShellLinkW(ComObject); SetLength(Result, MAX_PATH); OleCheck(ShellLink.GetPath(Result, MAX_PATH, FindData, SLGP_RAWPATH)); SetLength(Result, Pos(#0, Result) - 1); end; procedure IterateShortcuts(Path: string); var FindRec: TFindRec; ShortcutPath: string; TargetPath: string; begin Path := AddBackslash(Path); Log(Format('Looking for .lnk in [%s]', [Path])); if FindFirst(Path + '*.lnk', FindRec) then begin try repeat ShortcutPath := Path + FindRec.Name; TargetPath := GetLinkFileTarget(ShortcutPath); Log(Format('Target of shortcut [%s] is [%s]', [ShortcutPath, TargetPath])); until not FindNext(FindRec); finally FindClose(FindRec); end; end; end;