Sep 122007
 

Ever wondered how to resolve a shortcut! There is a hidden helper function if you are using MFC, it’s called AfxResolveShortcut. I customized it a bit, so that we can use it independently without MFC, and here is the finished product. 😉

BOOL ResolveShortcut( HWND hWnd_i,
                      LPCTSTR lpctszFileIn_i,
                      LPTSTR  lptszFileOut_o,
                      const int nPathLength_i )
{
    // Object for resolving link
    IShellLink* psl = NULL;
    *lptszFileOut_o = 0;   // assume failure

    if (!hWnd_i)
        return FALSE;

    SHFILEINFO info;
    if (( SHGetFileInfo(lpctszFileIn_i,
                        0,
                        &info,
                        sizeof(info),
                        SHGFI_ATTRIBUTES) == 0) || !(info.dwAttributes & SFGAO_LINK))
    {
        return FALSE;
    }

    CoInitialize( 0 );

    // Create instance
    HRESULT hCreateRes = CoCreateInstance( CLSID_ShellLink,
                                           0,
                                           CLSCTX_INPROC_SERVER,
                                           IID_IShellLink,
                                           reinterpret_cast<lpvoid *>( &psl ));
    if ( FAILED( hCreateRes ) || psl == NULL )
    {
        return FALSE;
    }

    IPersistFile *ppf = NULL;
    if (SUCCEEDED(psl->QueryInterface(IID_IPersistFile, (LPVOID*)&ppf)))
    {
        USES_CONVERSION; // T2COLE needs this
        if ( ppf != NULL && SUCCEEDED( ppf->Load( T2COLE( lpctszFileIn_i ), STGM_READ)) )
        {
            /* Resolve the link, this may post UI to find the link */
            if ( SUCCEEDED(psl->Resolve( hWnd_i,
                 			    SLR_ANY_MATCH)))
            {
                psl->GetPath(lptszFileOut_o, nPathLength_i, NULL, 0);
                ppf->Release();
                psl->Release();
                CoUninitialize();
                return TRUE;
            }
        }

        if (ppf != NULL)
            ppf->Release();
    }

    psl->Release();
    CoUninitialize();
    return FALSE;

}// End ResolveShortcut

//Lets test the above code...
int main()
{
  TCHAR chBuffer[MAX_PATH] = { 0 };
  ResolveShortcut( hSomeWindow,
                   _T( "C:\\shortcut to msdev.lnk" ), // Make sure the shortcut is there
                   chBuffer,
                   MAX_PATH );
  MessageBox( hSomeWindow, chBuffer, _T( "Hurray shortcut resolved" ), MB_OK | MB_ICONINFORMATION );
  return 0;
}// End main

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.