如何从microsoft office快捷方式获取targetPath,workingDir信息(在.Word 2013.lnk中)

时间:2014-01-18 11:02:51

标签: windows winapi windows-shell win32com advertised-shortcut

尝试使用IShellLink COM接口获取.LNK文件的信息。 它适用于许多应用程序shorcuts 但对于Microsoft Office应用程序快捷方式,它不提供正确的信息 例如:

在阅读ProgramData \ Microsoft \ Windows \ Start Menu \ Programs \ Microsoft Office 2013 \ Word 2013.lnk

IShellLink :: GetPath返回“C:\ Windows \ Installer {90150000-0011-0000-0000-0000000FF1CE} \ wordicon.exe”

不是C:\ Program Files(x86)\ Microsoft Office \ Office15 \ WINWORD.exe

有没有办法从这样的.lnk文件中获取目标信息。哪些Windows使用 双击shorcut时启动应用程序。

@Denis

这是我试过的C ++代码

IShellLinkDataList* comShellLinkDataList;
if (SUCCEEDED(psl->QueryInterface(IID_IShellLinkDataList,(void**)&comShellLinkDataList)))
{
    DWORD flags = 0;
    if (SUCCEEDED(comShellLinkDataList->GetFlags(&flags)))
    {
        if (flags & SLDF_HAS_DARWINID)
        {
            PIDLIST_ABSOLUTE pidList;
            if (SUCCEEDED(psl->GetIDList(&pidList)))
            {
                IShellFolder* shellFolder;
                PCITEMID_CHILD childItem;
                if (SUCCEEDED(SHBindToParent(pidList, IID_IShellFolder, (void**)&shellFolder, &childItem)))
                {
                    STRRET strRet;
                    if (SUCCEEDED(shellFolder->GetDisplayNameOf(childItem, SHGDN_NORMAL | SHGDN_FORPARSING, &strRet)))
                    {
                        TCHAR path[MAX_PATH] = {0};
                        if (SUCCEEDED(StrRetToBuf(&strRet, childItem, path, MAX_PATH)))
                        {
                            return path;
                        }
                    }                                    
                }                                
            }

        }
    }  
}

1 个答案:

答案 0 :(得分:0)

function GetExeNameFromShellLink(AShellLink: IShellLink): UnicodeString;
var List: IShellLinkDataList;
    Flags: DWORD;
    IDList: PItemIDList;
    ShellFolder: IShellFolder;
    ChildItem: PItemIDList;
    Attr: DWORD;
    StrRet: TStrRet;
begin
  if Succeeded(AShellLink.QueryInterface(IShellLinkDataList, List)) then
    try
      if Succeeded(List.GetFlags(Flags)) and (Flags and SLDF_HAS_DARWINID <> 0) then
        AShellLink.Resolve(0, SLR_INVOKE_MSI);
    finally
      List := nil;
    end;
  OleCheck(AShellLink.GetIDList(IDList));
  try
    OleCheck(SHBindToParent(IDList, IShellFolder, Pointer(ShellFolder), ChildItem));
    try
      OleCheck(ShellFolder.GetDisplayNameOf(ChildItem, SHGDN_NORMAL or SHGDN_FORPARSING, StrRet));
      case StrRet.uType of
        STRRET_WSTR:
          begin
            Result := StrRet.pOleStr;
            CoTaskMemFree(StrRet.pOleStr);
          end;
        STRRET_OFFSET:
          begin
            Inc(PByte(ChildItem), StrRet.uOffset);
            Result := UnicodeString(PAnsiChar(ChildItem));
          end;
        STRRET_CSTR:
          Result := UnicodeString(AnsiString(StrRet.cStr));
      else
        Result := '';
      end;
    finally
      ShellFolder := nil;
    end;
  finally
    CoTaskMemFree(IDList);
  end;
end;