2015-12-11 84 views
0

在我的Inno Setup安裝程序中,我需要確保某個文件的快捷方式存在於文件夾中。快捷方式的名稱是任意的,不在我的控制之下。我只知道它需要指向哪個文件。如果缺少快捷方式,我需要生成快捷方式。如果它已經存在,則不能再次創建。檢查Inno Setup中是否存在快捷方式

我想這是在某種程度上可以遍歷相關文件夾中的所有快捷方式文件,並檢查它們指向哪個文件。在a commentShared 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 Setup的Unicode版本作爲CodeAutomation2.iss例如頂部文中提到。 –

+0

我注意到另外兩件事: 第一:標誌SLGP_UNCPRIORITY在微軟網頁上被標記爲「不支持;不使用」。 第二:GetLinkFileTarget函數的返回值永遠不會等於鏈接應該指向的實際路徑。查看調試器中的返回路徑,我看到的唯一區別是返回的路徑末尾沒有'。此外,當我嘗試將htis字符串打印到日誌中時,該字符串的%s之後的每個文本都將被忽略。 –

+1

我已經[更正了答案](http://stackoverflow.com/posts/34221987/revisions)。有關詳細信息,請參閱例如[我如何從dll返回一個字符串到inno腳本](http://stackoverflow.com/q/21574264/850848) –

相關問題