• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 2479
  • Last Modified:

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

Hello,

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

or

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")
#endif
 
#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;
 
cleanup:
    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];
 
    CoInitialize(NULL);
 
    GetShortcutTarget(
     TEXT("C:\\Users\\Admin\\Desktop\\test.lnk"),
         szTarget, MAX_PATH);
 
    _tprintf(TEXT("The shortcut target is '%s'.\n"), szTarget);
 
    CoUninitialize();
    getchar();
    return 0;
}

Open in new window

0
Valty
Asked:
Valty
  • 5
  • 2
2 Solutions
 
jkrCommented:
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

0
 
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 ?
0
 
jkrCommented:
Well, these are the real names. The GUIDs are the names of subdirectories in "Installer" - take a look at that directory.
0
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

 
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 ?
0
 
ValtyAuthor Commented:
Hm... nobody have the solution ?
0
 
itsmeandnobodyelseCommented:
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
0
 
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)
0
 
ValtyAuthor Commented:
Nobody have another solution ?
0

Featured Post

VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

  • 5
  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now