2015-12-11 2 views
0

Dans mon programme d'installation Inno Setup, je dois m'assurer qu'un raccourci vers un certain fichier est présent dans un dossier. Le nom du raccourci est arbitraire et n'est pas sous mon contrôle. Je sais seulement quel fichier il doit pointer. Si le raccourci est manquant, j'ai besoin de générer le raccourci. S'il est déjà présent, il ne doit pas être créé à nouveau.Vérification de la présence d'un raccourci dans Inno Setup

Je suppose qu'il est en quelque sorte possible de parcourir tous les fichiers de raccourcis dans le dossier approprié et de vérifier le fichier vers lequel ils pointent. Dans a comment à une réponse à Shared Shortcuts/Icons, une interface IShellLink est mentionnée, mais je ne sais pas comment le rendre disponible dans la section Code. (Uses ShlObj; n'est pas reconnu)

Est-ce que quelqu'un a une suggestion comment je pourrais résoudre ce problème?

Répondre

1

Basé sur

Nécessite la version Unicode d'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; 
+0

ont parfaitement fonctionné dès que je me suis aperçu que je dois utiliser la version UNICODE de Inno setup comme mentionné dans le texte en haut de l'exemple CodeAutomation2.iss. –

+0

J'ai remarqué deux autres choses: Premièrement: L'indicateur SLGP_UNCPRIORITY est marqué comme "Non supporté, ne pas utiliser" sur la page Web de Microsoft. Deuxième: La valeur de retour de la fonction GetLinkFileTarget ne se compare jamais au chemin réel vers lequel le lien doit pointer. En regardant le chemin retourné dans le débogueur, la seule différence que je vois est que le chemin retourné n'a pas de 'à la fin. En outre, lorsque j'essaie d'imprimer cette chaîne dans le journal, chaque texte après le% s de cette chaîne est ignoré. –

+1

J'ai [corrigé la réponse] (http://stackoverflow.com/posts/34221987/revisions). Pour plus de détails, voir par exemple [Comment renvoyer une chaîne de dll à un script inno] (http://stackoverflow.com/q/21574264/850848) –