【问题标题】:How change shortcut path without update your icon?如何在不更新图标的情况下更改快捷方式路径?
【发布时间】:2021-12-01 17:22:24
【问题描述】:

我有以下代码可以更改一个快捷方式的路径。发生路径更改时,图标也会更新为新应用程序的图标。

如何在不更新快捷方式图标的情况下更改路径?

uses
 ActiveX,
 ComObj, 
 ShlObj;
 
 ...

function GetDesktopFolder: string;
var
  buf: array[0..MAX_PATH] of Char;
  pidList: PItemIDList;
begin
  Result := '';
  SHGetSpecialFolderLocation(Application.Handle, CSIDL_DESKTOP, pidList);
  if (pidList <> nil) then
    if (SHGetPathFromIDList(pidList, buf)) then
      Result := buf;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  MyObject: IUnknown;
  MySLink: IShellLink;
  MyPFile: IPersistFile;
  LnkPath, sExePath, sParams: string;
begin
  sParams := '';
  sExePath := 'C:\Program Files\Google\Chrome\Application\chrome.exe';
  LnkPath := GetDesktopFolder + '\Target.lnk';
  MyObject := CreateComObject(CLSID_ShellLink);
  MySLink := MyObject as IShellLink;
  MyPFile := MyObject as IPersistFile;

  with MySLink do
  begin
    SetDescription('');
    SetPath(PWideChar(sExePath));
    SetArguments(PWideChar(sParams));
    SetWorkingDirectory(PWideChar(ExtractFilePath(sExePath)));
    SetIconLocation(PWideChar(''), 0);
  end;

  MyPFile.Save(PWChar(WideString(LnkPath)), False);
  SHChangeNotify(SHCNE_UPDATEITEM, SHCNF_PATH, PWideChar(LnkPath), nil);
end;

【问题讨论】:

    标签: delphi delphi-10.4-sydney desktop-shortcut


    【解决方案1】:

    您无法阻止图标被更新。

    您可以在设置新路径之前通过IShellLink.GetIconLocation()检索当前图标,然后您可以在之后恢复图标,例如:

    function GetDesktopFolder(Wnd: HWND = 0): string;
    var
      buf: array[0..MAX_PATH] of Char;
    begin
      if Wnd = 0 then Wnd := Application.Handle;
      if Succeeded(SHGetFolderPath(Wnd, CSIDL_DESKTOP, 0, SHGFP_TYPE_CURRENT, buf)) then
        Result := IncludeTrailingPathDelimiter(buf)
      else
        Result := '';
    end;
    
    procedure TForm1.Button1Click(Sender: TObject);
    var
      MySLink: IShellLink;
      MyPFile: IPersistFile;
      sLnkPath, sExePath, sParams: string;
      szIconPath: array[0..MAX_PATH] of Char;
      iIconIndex: Integer;
      bHasIcon: Boolean;
    begin
      sParams := '';
      sExePath := 'C:\Program Files\Google\Chrome\Application\chrome.exe';
      sLnkPath := GetDesktopFolder(Handle) + 'Target.lnk';
    
      MySLink := CreateComObject(CLSID_ShellLink) as IShellLink;
      MyPFile := MySLink as IPersistFile;
    
      if Succeeded(MyPFile.Load(PChar(sLnkPath), STGM_READ)) then
      begin
        MySLink.Resolve(Handle, 0); 
        bHasIcon := Succeeded(MySLink.GetIconLocation(szIconPath, Length(szIconPath), @iIconIndex));
      end;
    
      with MySLink do
      begin
        SetDescription(PChar(''));
        SetPath(PChar(sExePath));
        SetArguments(PChar(sParams));
        SetWorkingDirectory(PChar(ExtractFilePath(sExePath)));
        if bHasIcon then
          SetIconLocation(szIconPath, iIconIndex)
        else
          SetIconLocation(PChar(''), 0);
      end;
    
      MyPFile.Save(PChar(sLnkPath), False);
      SHChangeNotify(SHCNE_UPDATEITEM, SHCNF_PATH, PChar(sLnkPath), nil);
    end;
    

    【讨论】:

    • 只有一个好奇:是否可以通过快捷方式的右键 > 属性看到的方式更改路径和工作目录?例如:假设我想将 Mozilla Firefox 的路径和工作目录更改为 Google Chrome,之后,here 可以在更新前看到原始数据,就像没有任何改变一样?
    • 当然不是。为什么你会想要那个?
    • 默认情况下,快捷方式没有分配任何图标。因此,Windows 在这种情况下所做的就是尽可能从目标文件中检索图标并将其用作快捷方式图标。这就是为什么更改快捷方式目标也会更改快捷方式图标的原因。但是,如果您为快捷方式分配一个图标,那么无论快捷方式目标是什么,都会显示该图标。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-11-01
    • 2016-11-26
    • 2017-11-15
    • 1970-01-01
    • 2017-09-27
    • 2014-08-13
    • 1970-01-01
    相关资源
    最近更新 更多