windows installation inno-setup shortcuts pascalscript

windows - Compruebe la presencia de un atajo en Inno Setup



installation inno-setup (1)

En mi instalador de Inno Setup, necesito asegurarme de que haya un acceso directo a un determinado archivo en una carpeta. El nombre del atajo es arbitrario y no está bajo mi control. Solo sé a qué archivo debe apuntar. Si falta el acceso directo, necesito generar el acceso directo. Si ya está presente, no debe crearse nuevamente.

Supongo que de alguna manera es posible recorrer todos los archivos de acceso directo en la carpeta correspondiente y verificar a qué archivo apuntan. En un comentario de una respuesta a accesos directos / iconos compartidos , se menciona una interfaz IShellLink , pero no sé cómo hacer que esté disponible en la sección Code . ( Uses ShlObj; no se reconoce)

¿Alguien tiene una sugerencia de cómo podría resolver este problema?


Residencia en

Requiere la versión Unicode de 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;