2015-12-11 9 views
0

В моем установщике Inno Setup мне нужно убедиться, что ярлык для определенного файла присутствует в папке. Имя ярлыка произвольно и не под моим контролем. Я знаю только, в каком файле он должен указывать. Если ярлык отсутствует, мне нужно сгенерировать ярлык. Если он уже присутствует, он не должен быть создан снова.Проверьте наличие ярлыка в Inno Setup

Я предполагаю, что это возможно, чтобы выполнить итерацию всех ярлыков в соответствующей папке и проверить, к какому файлу они указывают. В a comment на ответ Shared Shortcuts/Icons указан интерфейс IShellLink, но я не знаю, как сделать его доступным в разделе Code. (Uses ShlObj; не признается)

Есть ли у кого-нибудь предложение, как я мог бы решить эту проблему?

ответ

1

на основе

Требуется 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; 
+0

работал отлично, как только я понял, что мне нужно использовать версию Юникода установки Inno, как указано в верхнем тексте примера CodeAutomation2.iss. –

+0

Я заметил еще две вещи: Первый: флаг SLGP_UNCPRIORITY помечен как «Неподдерживаемый, не используйте» на веб-странице Microsoft. Второе: возвращаемое значение функции GetLinkFileTarget никогда не сравнивается с фактическим путем, на который должна указывать ссылка. Глядя на возвращенный путь в отладчике, единственное различие, которое я вижу, это то, что возвращенный путь не имеет «в конце». Кроме того, когда я пытаюсь напечатать htis строку в журнале, каждый текст после% s этой строки игнорируется. –

+1

Я [исправил ответ] (http://stackoverflow.com/posts/34221987/revisions). Для получения дополнительной информации см., Например, [Как вернуть строку из dll в скрипт inno] (http://stackoverflow.com/q/21574264/850848) –

 Смежные вопросы

  • Нет связанных вопросов^_^