Wednesday, April 15, 2009

How to resolve a shortcut!

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( &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" ),

chBuffer,

MAX_PATH );

MessageBox( hSomeWindow, chBuffer,

_T( "Hurray shortcut resolved" ),

MB_OK | MB_ICONINFORMATION );

return 0;

}// End main

No comments: