Как получить targetPath, workingDir информацию из мерцаний офиса Microsoft Office (например, Word 2013.lnk)

73
9

Пробовал использовать интерфейс IShellLink COM для получения информации о файлах.LNK. Он отлично подходит для многих приложений. Но для ярлыков приложений 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. какие окна используют для запуска приложения при двойном нажатии на shorcut.

@Денис

Вот код 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;
}
}
}
}

}
}
}

спросил(а) 2014-01-18T14:02:00+04:00 6 лет, 2 месяца назад
1
Решение
95

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;

ответил(а) 2014-01-18T17:38:00+04:00 6 лет, 2 месяца назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема