【问题标题】:Check for existence of a shortcut pointing to a specific target in Inno Setup在 Inno Setup 中检查是否存在指向特定目标的快捷方式
【发布时间】:2016-03-17 05:04:29
【问题描述】:

在我的 Inno Setup 安装程序中,我需要确保文件夹中存在某个文件的快捷方式。快捷方式的名称是任意的,不受我控制。我只知道它需要指向哪个文件。如果缺少快捷方式,我需要生成快捷方式。如果它已经存在,则不得再次创建。

我猜想以某种方式遍历相关文件夹中的所有快捷方式文件并检查它们指向哪个文件是可能的。在a commentShared Shortcuts/Icons 的回答中,提到了IShellLink 接口,但我不知道如何使其在Code 部分可用。 (Uses ShlObj; 无法识别)

有没有人建议我如何解决这个问题?

【问题讨论】:

    标签: windows installation inno-setup shortcut pascalscript


    【解决方案1】:

    基于

    需要 Inno Setup 的 Unicode 版本(Inno Setup 6 的唯一版本)。

    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;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-04-05
      • 1970-01-01
      • 1970-01-01
      • 2022-11-04
      • 1970-01-01
      • 2011-05-22
      • 1970-01-01
      相关资源
      最近更新 更多