C++ Builder
| Главная | Уроки | Статьи | FAQ | Форум | Downloads | Литература | Ссылки | RXLib | Диски |

 
Получение пути из ярлыков (.lnk)
b0nes
  Отправлено: 06.08.2004, 16:48


Ученик-кочегар

Группа: Участник
Сообщений: 5



Может кто сталкивался с моей проблемой и знает ее решение (очень надеюсь:)?
Моя прога работает с ярлыками, получает из низ инфу типа пути к файлу, директории, пути к иконке и т.п. До недавнего времени все было ок, но вот столкнулся я со странным типом ярлыков. К ним относятся офисовские ярлыки (MS Office XP, 2000, 2003) и даже ACDSee 6.0. Странность заключается в том, что если получать путь из такого ярлыка, то получишь совсем не путь к программе. Например, для ярлыка ворда я получаю след. путь:
CODE
"C:\WINDOWS\Installer\{90110419-6000-11D3-8CFE-0150048383C9}\wordicon.exe"

Этот полученный файл содержит только лишь иконку ворда, и, есесьно, если запустить его, то ворд не запустится sad.gif.
А как же тогда получить нормальный путь типа "с:\program files\microsoft office\office11\winword.exe" (ну это я к примеру, не надо меня сразу в реестр отправлять за ключом "HKLM\software\microsoft\windows\currentversion\app paths\winword.exe", это не поможет — нужно универсальное средство)?
С ярлыками я работаю через интерфейс IShellLink.
Кстати, мне тут посоветовали работать с такими ярлыками через интерфейс IMoniker. Прочитал я пару статей про них (моникеров этих), но все равно не понял, как через них путь получить, может читал плохо:-). Нет времени у меня сейчас читать книжки по КОМу, не думаю, что там много чего написать нужно, чтоб все работало )).

Надеюсь на вашу помощь, уважаемый All!

Андрей
b0nes
  Отправлено: 08.08.2004, 16:17


Ученик-кочегар

Группа: Участник
Сообщений: 5



Ура, нашел решение!
Если кому интересно, вот код.
CODE

//В Edit1->Text должен быть путь к ярлыку.
//В Memo1 будем кидать результат.
//На событие OnClick кнопки Button1 впишем след. код:

String strFileNameAndPath = Edit1->Text;
String strExeName = "";

IShellLink* psl;
IPersistFile* ppf;
HRESULT hres;
char szEXEPath[MAX_PATH];
WIN32_FIND_DATA wfd;

CoInitialize(NULL);

// Get a pointer to the IShellLink interface.
hres = ::CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (void**)&psl);

if (SUCCEEDED(hres)){
// Get a pointer to the IPersistFile interface.
hres = psl->QueryInterface(IID_IPersistFile,(void**)&ppf);
if (SUCCEEDED(hres)){
 // Ensure string is Unicode.
 wchar_t lpWideCharStr[MAX_PATH];
 MultiByteToWideChar(CP_ACP, 0,strFileNameAndPath.c_str(), -1, lpWideCharStr, MAX_PATH);
 hres = ppf->Load(lpWideCharStr, STGM_READ);
 if (SUCCEEDED(hres)){
  LPITEMIDLIST pidl = NULL;
  psl->Resolve(Handle, SLR_INVOKE_MSI | SLR_NOUPDATE | SLR_NO_UI);
  psl->GetIDList(&pidl);
  SHGetPathFromIDList(pidl, szEXEPath);
   }
 }

// Release the pointer to the IPersistFile interface.
ppf->Release();
}

// Release the pointer to the IShellLink interface.
hres = psl->Release();

CoUninitialize();
strExeName = (String)szEXEPath;
Memo1->Clear();
Memo1->Lines->Add(strExeName);

Вот и все!
Удачи всем :-))

Вернуться в Вопросы программирования в C++Builder