2015-12-11 60 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) –

相关问题