Click here to Skip to main content
11,412,833 members (73,507 online)
Click here to Skip to main content

How to create and resolve a shortcut

, 6 Oct 2003 CPOL
Rate this:
Please Sign up or sign in to vote.
This article presents 2 ready-to-use functions to create and resolve a shortcut.

Introduction

Shortcut is a file with an extension .lnk. Each of these files contain a special COM object that points to another file. Usually, when you try to open a .lnk file, the system opens a file which this shortcut points to.

Let's do the following experiment. Create a text file (file with an extension .txt) somewhere. Then create a shortcut pointing to this file (send me a private e-mail if you do not know how to create a shortcut manually). Then try to open the shortcut with Microsoft Word, using File->Open command and select just created shortcut. MS Word will do it correctly: it will open the text file that is pointed by this shortcut. Now do the same with Notepad. Instead of the text file content, you will see garbage. It means that Notepad has no idea how to deal with shortcuts.

So we came to a conclusion: in Windows a program should have a built-in support for shortcuts in order to handle them correctly.

In this article I will show how to do it. I will present 2 functions: how to create and resolve the shortcut. The code is well commented (in my opinion) and self-explanatory.

Code

/**********************************************************************
* Function......: CreateShortcut
* Parameters....: lpszFileName - string that specifies a valid file name
*          lpszDesc - string that specifies a description for a 
                             shortcut
*          lpszShortcutPath - string that specifies a path and 
                                     file name of a shortcut
* Returns.......: S_OK on success, error code on failure
* Description...: Creates a Shell link object (shortcut)
**********************************************************************/
HRESULT CreateShortcut(/*in*/ LPCTSTR lpszFileName, 
                    /*in*/ LPCTSTR lpszDesc, 
                    /*in*/ LPCTSTR lpszShortcutPath)
{
    HRESULT hRes = E_FAIL;
    DWORD dwRet = 0;
    CComPtr<IShellLink> ipShellLink;
        // buffer that receives the null-terminated string 
        // for the drive and path
    TCHAR szPath[MAX_PATH];    
        // buffer that receives the address of the final 
        //file name component in the path
    LPTSTR lpszFilePart;    
    WCHAR wszTemp[MAX_PATH];
        
    // Retrieve the full path and file name of a specified file
    dwRet = GetFullPathName(lpszFileName, 
                       sizeof(szPath) / sizeof(TCHAR), 
                       szPath, &lpszFilePart);
    if (!dwRet)                                        
        return hRes;

    // Get a pointer to the IShellLink interface
    hRes = CoCreateInstance(CLSID_ShellLink,
                            NULL, 
                            CLSCTX_INPROC_SERVER,
                            IID_IShellLink,
                            (void**)&ipShellLink);

    if (SUCCEEDED(hRes))
    {
        // Get a pointer to the IPersistFile interface
        CComQIPtr<IPersistFile> ipPersistFile(ipShellLink);

        // Set the path to the shortcut target and add the description
        hRes = ipShellLink->SetPath(szPath);
        if (FAILED(hRes))
            return hRes;

        hRes = ipShellLink->SetDescription(lpszDesc);
        if (FAILED(hRes))
            return hRes;

        // IPersistFile is using LPCOLESTR, so make sure 
                // that the string is Unicode
#if !defined _UNICODE
        MultiByteToWideChar(CP_ACP, 0, 
                       lpszShortcutPath, -1, wszTemp, MAX_PATH);
#else
        wcsncpy(wszTemp, lpszShortcutPath, MAX_PATH);
#endif

        // Write the shortcut to disk
        hRes = ipPersistFile->Save(wszTemp, TRUE);
    }

    return hRes;
}

/*********************************************************************
* Function......: ResolveShortcut
* Parameters....: lpszShortcutPath - string that specifies a path 
                                     and file name of a shortcut
*          lpszFilePath - string that will contain a file name
* Returns.......: S_OK on success, error code on failure
* Description...: Resolves a Shell link object (shortcut)
*********************************************************************/
HRESULT ResolveShortcut(/*in*/ LPCTSTR lpszShortcutPath,
                        /*out*/ LPTSTR lpszFilePath)
{
    HRESULT hRes = E_FAIL;
    CComPtr<IShellLink> ipShellLink;
        // buffer that receives the null-terminated string 
        // for the drive and path
    TCHAR szPath[MAX_PATH];     
        // buffer that receives the null-terminated 
        // string for the description
    TCHAR szDesc[MAX_PATH]; 
        // structure that receives the information about the shortcut
    WIN32_FIND_DATA wfd;    
    WCHAR wszTemp[MAX_PATH];

    lpszFilePath[0] = '\0';

    // Get a pointer to the IShellLink interface
    hRes = CoCreateInstance(CLSID_ShellLink,
                            NULL, 
                            CLSCTX_INPROC_SERVER,
                            IID_IShellLink,
                            (void**)&ipShellLink); 

    if (SUCCEEDED(hRes)) 
    { 
        // Get a pointer to the IPersistFile interface
        CComQIPtr<IPersistFile> ipPersistFile(ipShellLink);

        // IPersistFile is using LPCOLESTR, 
                // so make sure that the string is Unicode
#if !defined _UNICODE
        MultiByteToWideChar(CP_ACP, 0, lpszShortcutPath,
                                       -1, wszTemp, MAX_PATH);
#else
        wcsncpy(wszTemp, lpszShortcutPath, MAX_PATH);
#endif

        // Open the shortcut file and initialize it from its contents
        hRes = ipPersistFile->Load(wszTemp, STGM_READ); 
        if (SUCCEEDED(hRes)) 
        {
            // Try to find the target of a shortcut, 
                        // even if it has been moved or renamed
            hRes = ipShellLink->Resolve(NULL, SLR_UPDATE); 
            if (SUCCEEDED(hRes)) 
            {
                // Get the path to the shortcut target
                hRes = ipShellLink->GetPath(szPath, 
                                     MAX_PATH, &wfd, SLGP_RAWPATH); 
                if (FAILED(hRes))
                    return hRes;

                // Get the description of the target
                hRes = ipShellLink->GetDescription(szDesc,
                                             MAX_PATH); 
                if (FAILED(hRes))
                    return hRes;

                lstrcpyn(lpszFilePath, szPath, MAX_PATH); 
            } 
        } 
    } 

    return hRes;
}

Using the code

The following code will show how you may use these functions.

void HowToCreateShortcut()
{
    LPCTSTR lpszFileName = _T("C:\\Work\\Window.exe");
    LPCTSTR lpszShortcutDesc = _T("Anything can go here");
    LPCTSTR lpszShortcutPath = 
_T("C:\\Documents and Settings\\Administrator\\Desktop\\Sample Shortcut.lnk");

    CreateShortcut(lpszFileName, lpszShortcutDesc, lpszShortcutPath);
}

void HowToResolveShortcut()
{
    LPCTSTR lpszShortcutPath = 
_T("C:\\Documents and Settings\\Administrator\\Desktop\\Sample Shortcut.lnk");
    TCHAR szFilePath[MAX_PATH];

    ResolveShortcut(lpszShortcutPath, szFilePath);
}

That's it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Igor Vigdorchik
Web Developer
United States United States
No Biography provided

Comments and Discussions

 
Generalproblem Pin
Mister Transistor at 30-Jun-04 2:48
memberMister Transistor30-Jun-04 2:48 
GeneralRe: problem Pin
Igor Vigdorchik at 30-Jun-04 4:21
memberIgor Vigdorchik30-Jun-04 4:21 
GeneralRe: problem Pin
Mister Transistor at 2-Jul-04 1:57
memberMister Transistor2-Jul-04 1:57 
GeneralRe: problem Pin
Igor Vigdorchik at 2-Jul-04 5:32
memberIgor Vigdorchik2-Jul-04 5:32 
GeneralThanks Pin
basudevc at 7-Apr-04 4:55
sussbasudevc7-Apr-04 4:55 
GeneralRe: Thanks Pin
Igor Vigdorchik at 10-Apr-04 3:36
memberIgor Vigdorchik10-Apr-04 3:36 
GeneralMissing Directory Pin
bruno leclerc at 24-Mar-04 0:32
memberbruno leclerc24-Mar-04 0:32 
GeneralRe: Missing Directory Pin
ronyy7 at 24-Mar-04 15:37
memberronyy724-Mar-04 15:37 
GeneralRe: Missing Directory Pin
Igor Vigdorchik at 24-Mar-04 16:50
memberIgor Vigdorchik24-Mar-04 16:50 
Generalfile name &gt; MAX_PATH Pin
ronyy7 at 17-Mar-04 14:09
memberronyy717-Mar-04 14:09 
QuestionWhat to include Pin
--.- at 10-Feb-04 16:38
member--.-10-Feb-04 16:38 
AnswerRe: What to include Pin
Rivael at 11-May-04 1:00
sussRivael11-May-04 1:00 
Generalget info from MSOffice shortcut Pin
Sergey K at 3-Feb-04 6:42
memberSergey K3-Feb-04 6:42 
GeneralRe: get info from MSOffice shortcut Pin
Igor Vigdorchik at 3-Feb-04 14:43
memberIgor Vigdorchik3-Feb-04 14:43 
GeneralRe: get info from MSOffice shortcut Pin
Sergey K at 3-Feb-04 20:53
memberSergey K3-Feb-04 20:53 
GeneralRe: get info from MSOffice shortcut Pin
Igor Vigdorchik at 4-Feb-04 14:47
memberIgor Vigdorchik4-Feb-04 14:47 
GeneralRe: get info from MSOffice shortcut Pin
Sergey K at 4-Feb-04 21:19
memberSergey K4-Feb-04 21:19 
GeneralRe: get info from MSOffice shortcut Pin
Shaun Harrington at 28-Jun-06 15:27
memberShaun Harrington28-Jun-06 15:27 
GeneralRe: get info from MSOffice shortcut [modified] Pin
Shaun Harrington at 28-Jun-06 16:12
memberShaun Harrington28-Jun-06 16:12 
GeneralRe: get info from MSOffice shortcut Pin
Shaun Harrington at 28-Jun-06 16:15
memberShaun Harrington28-Jun-06 16:15 
GeneralRe: get info from MSOffice shortcut Pin
Igor Vigdorchik at 28-Jun-06 17:50
memberIgor Vigdorchik28-Jun-06 17:50 
GeneralRe: get info from MSOffice shortcut Pin
Shaun Harrington at 30-Jun-06 5:07
memberShaun Harrington30-Jun-06 5:07 
GeneralRe: get info from MSOffice shortcut Pin
Igor Vigdorchik at 6-Jul-06 12:14
memberIgor Vigdorchik6-Jul-06 12:14 
GeneralRe: get info from MSOffice shortcut Pin
Shaun Harrington at 21-Jul-06 0:46
memberShaun Harrington21-Jul-06 0:46 
GeneralRe: get info from MSOffice shortcut Pin
BillJam11 at 12-Jul-06 7:04
memberBillJam1112-Jul-06 7:04 
GeneralRe: get info from MSOffice shortcut Pin
Radu Sebastian LAZIN at 14-Aug-06 13:09
memberRadu Sebastian LAZIN14-Aug-06 13:09 
GeneralCreate Desktop Shortcut Pin
scar_me at 28-Jan-04 19:07
memberscar_me28-Jan-04 19:07 
QuestionThere's a way to do this procedures in C? Pin
Chulips at 16-Jan-04 1:39
memberChulips16-Jan-04 1:39 
AnswerRe: There's a way to do this procedures in C? Pin
Igor Vigdorchik at 19-Jan-04 18:30
memberIgor Vigdorchik19-Jan-04 18:30 
GeneralRe: There's a way to do this procedures in C? Pin
Chulips at 21-Jan-04 10:15
memberChulips21-Jan-04 10:15 
GeneralRe: There's a way to do this procedures in C? Pin
Igor Vigdorchik at 21-Jan-04 13:47
memberIgor Vigdorchik21-Jan-04 13:47 
GeneralRe: There's a way to do this procedures in C? Pin
John T at 5-Apr-04 9:26
memberJohn T5-Apr-04 9:26 
GeneralRe: There's a way to do this procedures in C? Pin
John T at 5-Apr-04 9:28
memberJohn T5-Apr-04 9:28 
GeneralRe: There's a way to do this procedures in C? Pin
Mike D. at 1-Jul-04 12:34
memberMike D.1-Jul-04 12:34 
Generalshortcut to network connection Pin
Simon Lao at 17-Oct-03 12:35
memberSimon Lao17-Oct-03 12:35 
GeneralRe: shortcut to network connection Pin
Igor Vigdorchik at 17-Oct-03 19:55
memberIgor Vigdorchik17-Oct-03 19:55 
GeneralRe: shortcut to network connection Pin
dberindei at 20-Oct-03 1:19
memberdberindei20-Oct-03 1:19 
GeneralRe: shortcut to network connection Pin
Igor Vigdorchik at 8-Nov-03 12:09
memberIgor Vigdorchik8-Nov-03 12:09 
GeneralRe: shortcut to network connection Pin
ohadhawk at 7-Jan-04 10:41
sussohadhawk7-Jan-04 10:41 
GeneralRe: shortcut to network connection Pin
ohadhawk at 7-Jan-04 10:43
sussohadhawk7-Jan-04 10:43 
GeneralRe: shortcut to network connection Pin
Igor Vigdorchik at 7-Jan-04 14:14
memberIgor Vigdorchik7-Jan-04 14:14 
QuestionCan anyone tell me the structure of .lnk.... Pin
Kamal Shankar at 9-Oct-03 9:05
memberKamal Shankar9-Oct-03 9:05 
GeneralNotepad opens shortcuts ! Pin
gopya at 8-Oct-03 3:50
membergopya8-Oct-03 3:50 
GeneralRe: Notepad opens shortcuts ! Pin
Igor Vigdorchik at 8-Oct-03 16:27
memberIgor Vigdorchik8-Oct-03 16:27 
GeneralArticle has been updated today Pin
Igor Vigdorchik at 7-Oct-03 7:24
memberIgor Vigdorchik7-Oct-03 7:24 
QuestionAm I Missing Something? Pin
jmarcos at 5-Oct-03 2:24
memberjmarcos5-Oct-03 2:24 
AnswerRe: Am I Missing Something? Pin
Igor Vigdorchik at 5-Oct-03 17:19
memberIgor Vigdorchik5-Oct-03 17:19 
GeneralRe: Am I Missing Something? Pin
Paul Selormey at 6-Oct-03 5:31
memberPaul Selormey6-Oct-03 5:31 
GeneralRe: Am I Missing Something? Pin
Igor Vigdorchik at 6-Oct-03 6:08
memberIgor Vigdorchik6-Oct-03 6:08 
AnswerRe: Am I Missing Something? Pin
Paul Selormey at 6-Oct-03 5:29
memberPaul Selormey6-Oct-03 5:29 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web01 | 2.8.150427.1 | Last Updated 7 Oct 2003
Article Copyright 2003 by Igor Vigdorchik
Everything else Copyright © CodeProject, 1999-2015
Layout: fixed | fluid