C++ problem to resolve .lnk files with IShellLink:GetPath()


I use the IShellLink:GetPath() method to resolve .lnk files.

It works fine with the most of my .lnk files (like TuneUp, NotePad, and all Windows programs)

But, with programs like Safari or Adobe Reader, the method just returns this :

C:/Windows/Installer/{xxxxxxxx}/SafariIco.exe for Safari


C:/Windows/Installer/{yyyyyyyy}/SC_Reader.exe for Adobe Reader

How can I get the real path of theses .lnk files WITH DEV-CPP ?

My actual code is attached.

Thanks you in advance !
#include <windows.h>
#include <objidl.h>   /* For IPersistFile */
#include <shlobj.h>   /* For IShellLink */
#if defined(_MSC_VER)
#pragma comment(lib, "ole32.lib")
#pragma comment(lib, "uuid.lib")
#include <stdio.h>
#include <tchar.h>
BOOL GetShortcutTarget(LPCTSTR szShortcutFile, LPTSTR szTarget, SIZE_T cchTarget)
    IShellLink*    psl     = NULL;
    IPersistFile*  ppf     = NULL;
    BOOL           bResult = FALSE;
    if (FAILED( CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (void **) &psl) ))
        goto cleanup;
    if (FAILED( psl->QueryInterface(IID_IPersistFile, (void **) &ppf) ))
        goto cleanup;
#   if !defined(UNICODE)
        WCHAR wsz[MAX_PATH];
        if (0 == MultiByteToWideChar(CP_ACP, 0, szShortcutFile, -1, wsz, MAX_PATH) )
            goto cleanup;
#   else
        LPCWSTR wsz = szShortcutFile;
#   endif
    if (FAILED( ppf->Load(wsz, STGM_READ) ))
        goto cleanup;
    if (NOERROR != psl->GetPath(szTarget, cchTarget, NULL, 0) )
        goto cleanup;
    bResult = TRUE;
    if (ppf) ppf->Release();
    if (psl) psl->Release();
    if (!bResult && cchTarget != 0) szTarget[0] = TEXT('\0');
    return bResult;
int main(void)
    TCHAR szTarget[MAX_PATH];
         szTarget, MAX_PATH);
    _tprintf(TEXT("The shortcut target is '%s'.\n"), szTarget);
    return 0;

Open in new window

Who is Participating?
itsmeandnobodyelseConnect With a Mentor Commented:
You could/should pass flag  SLGP_RAWPATH  and/or SLGP_UNCPRIORITY as 4th argument to GetPath.

You also could/should pass an address of a WIN32_FIND_DATA struct as 3rd argument. The WIN32_FIND_DATA has a cFileName member which should contain the absolute path of the file.

   WIN32_FIND_DATA wfd = { 0 };
   if (NOERROR != psl->GetPath(szTarget, cchTarget, &wfd, SLGP_UNCPRIORITY ) )
        goto cleanup;

  // now check for wfd.cFileName
Um, I assume the "{xxxxxxxx}" part is actually a GUID - then these *are* the real file names, check them out. E.g. a short excerpt from my Windows\Installer directory:
04.02.2008  05:11    <DIR>          {AC76BA86-7AD7-5464-3428-800000000003}
05.05.2008  05:40    <DIR>          {C04E32E0-0416-434D-AFB9-6969D703A9EF}
04.08.2007  10:37    <DIR>          {CE386A4E-D0DA-4208-8235-BCE43275C694}
07.08.2007  11:53    <DIR>          {D7E04009-B191-4E9D-9D2D-1BBE57BD8A42}

Open in new window

ValtyAuthor Commented:
Yes of course, I have GUID, not the "xxxxxxx" : it was just for the example. But how to retreive the real names via the GUID ?
Free Tool: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

jkrConnect With a Mentor Commented:
Well, these are the real names. The GUIDs are the names of subdirectories in "Installer" - take a look at that directory.
ValtyAuthor Commented:
But, the programs into these directories are not valids.

Eg :

I have a Safari.lnk who give me this path => C:/Windows/Installer/{xxxxxxxx}/SafariIco.exe

But this path is not the program path ! SafariIco.exe is not a valid Win32 exe.

Safari is really located at C:/Program Files/Safari/Safari.exe

Do you understand ?
ValtyAuthor Commented:
Hm... nobody have the solution ?
ValtyAuthor Commented:
Hello, thanks for your answer

I have tested with SLGP_RAWPATH  and/or SLGP_UNCPRIORITY => no changes

I have also tested with WIN32_FIND_DATA wfd = { 0 }; and a printf with wfd.cFileName, it just returns "taller" or "taller\{XXXX-XXXX-XXX" (the GUID is not complete)
ValtyAuthor Commented:
Nobody have another solution ?
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.