36

I need to programmatically create a shortcut using C++.

How can I do this using Win32 SDK?

What API function can be used for this purpose?

4 Answers 4

32

Try Windows Shell Links. This page also contains a C++ example. Descriptive Snippet:

Using Shell Links

This section contains examples that demonstrate how to create and resolve shortcuts from within a Win32-based application. This section assumes you are familiar with Win32, C++, and OLE COM programming.

EDIT: Adding the code sample in case the link dies (and MSDN links do die often.)

// CreateLink - Uses the Shell's IShellLink and IPersistFile interfaces 
//              to create and store a shortcut to the specified object. 
//
// Returns the result of calling the member functions of the interfaces. 
//
// Parameters:
// lpszPathObj  - Address of a buffer that contains the path of the object,
//                including the file name.
// lpszPathLink - Address of a buffer that contains the path where the 
//                Shell link is to be stored, including the file name.
// lpszDesc     - Address of a buffer that contains a description of the 
//                Shell link, stored in the Comment field of the link
//                properties.

#include "stdafx.h"
#include "windows.h"
#include "winnls.h"
#include "shobjidl.h"
#include "objbase.h"
#include "objidl.h"
#include "shlguid.h"

HRESULT CreateLink(LPCWSTR lpszPathObj, LPCSTR lpszPathLink, LPCWSTR lpszDesc) 
{ 
    HRESULT hres; 
    IShellLink* psl; 

    // Get a pointer to the IShellLink interface. It is assumed that CoInitialize
    // has already been called.
    hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (LPVOID*)&psl); 
    if (SUCCEEDED(hres)) 
    { 
        IPersistFile* ppf; 

        // Set the path to the shortcut target and add the description. 
        psl->SetPath(lpszPathObj); 
        psl->SetDescription(lpszDesc); 

        // Query IShellLink for the IPersistFile interface, used for saving the 
        // shortcut in persistent storage. 
        hres = psl->QueryInterface(IID_IPersistFile, (LPVOID*)&ppf); 

        if (SUCCEEDED(hres)) 
        { 
            WCHAR wsz[MAX_PATH]; 

            // Ensure that the string is Unicode. 
            MultiByteToWideChar(CP_ACP, 0, lpszPathLink, -1, wsz, MAX_PATH); 

            // Save the link by calling IPersistFile::Save. 
            hres = ppf->Save(wsz, TRUE); 
            ppf->Release(); 
        } 
        psl->Release(); 
    } 
    return hres; 
Sign up to request clarification or add additional context in comments.

2 Comments

You didn't initialize com library... also uninitialize it when you finished
FYI the link has changed (the anchor tag changed). Here is the new one (if you don't like scrolling_=) learn.microsoft.com/en-au/windows/win32/shell/…
8

Here is a c++ sample code based on William Rayer code on codeproject.com

header file (ShortcutProvider.h):

#include <Windows.h>

class ShortcutProvider
{
public:
    /*
    -------------------------------------------------------------------
    Description:
    Creates the actual 'lnk' file (assumes COM has been initialized).

    Parameters:
    pszTargetfile    - File name of the link's target.
    pszTargetargs    - Command line arguments passed to link's target.
    pszLinkfile      - File name of the actual link file being created.
    pszDescription   - Description of the linked item.
    iShowmode        - ShowWindow() constant for the link's target.
    pszCurdir        - Working directory of the active link. 
    pszIconfile      - File name of the icon file used for the link.
    iIconindex       - Index of the icon in the icon file.

    Returns:
    HRESULT value >= 0 for success, < 0 for failure.
    --------------------------------------------------------------------
    */
    HRESULT Create(LPSTR pszTargetfile, LPSTR pszTargetargs,
        LPSTR pszLinkfile, LPSTR pszDescription, 
        int iShowmode, LPSTR pszCurdir, 
        LPSTR pszIconfile, int iIconindex);
};

Source File (ShortcutProvide.cpp):

#include "ShortcutProvider.h"
#include <Windows.h>
#include <shlobj.h>
#include <winnls.h>
#include <shobjidl.h>
#include <objbase.h>
#include <objidl.h>
#include <shlguid.h>


HRESULT ShortcutProvider::Create(LPSTR pszTargetfile, LPSTR pszTargetargs,
                                LPSTR pszLinkfile, LPSTR pszDescription, 
                                int iShowmode, LPSTR pszCurdir, 
                                LPSTR pszIconfile, int iIconindex)
  {
    HRESULT       hRes;                  /* Returned COM result code */
    IShellLink*   pShellLink;            /* IShellLink object pointer */
    IPersistFile* pPersistFile;          /* IPersistFile object pointer */
    WCHAR wszLinkfile[MAX_PATH]; /* pszLinkfile as Unicode 
                                            string */
    int           iWideCharsWritten;     /* Number of wide characters 
                                            written */
    CoInitialize(NULL);
    hRes = E_INVALIDARG;
    if (
         (pszTargetfile != NULL) && (strlen(pszTargetfile) > 0) &&
         (pszTargetargs != NULL) &&
         (pszLinkfile != NULL) && (strlen(pszLinkfile) > 0) &&
         (pszDescription != NULL) && 
         (iShowmode >= 0) &&
         (pszCurdir != NULL) && 
         (pszIconfile != NULL) &&
         (iIconindex >= 0)
       )
    {
      hRes = CoCreateInstance(
        CLSID_ShellLink,     /* pre-defined CLSID of the IShellLink 
                                 object */
        NULL,                 /* pointer to parent interface if part of 
                                 aggregate */
        CLSCTX_INPROC_SERVER, /* caller and called code are in same 
                                 process */
        IID_IShellLink,      /* pre-defined interface of the 
                                 IShellLink object */
        (LPVOID*)&pShellLink);         /* Returns a pointer to the IShellLink 
                                 object */
      if (SUCCEEDED(hRes))
      {
        /* Set the fields in the IShellLink object */
        hRes = pShellLink->SetPath(pszTargetfile);
        hRes = pShellLink->SetArguments(pszTargetargs);
        if (strlen(pszDescription) > 0)
        {
          hRes = pShellLink->SetDescription(pszDescription);
        }
        if (iShowmode > 0)
        {
          hRes = pShellLink->SetShowCmd(iShowmode);
        }
        if (strlen(pszCurdir) > 0)
        {
          hRes = pShellLink->SetWorkingDirectory(pszCurdir);
        }
        if (strlen(pszIconfile) > 0 && iIconindex >= 0)
        {
          hRes = pShellLink->SetIconLocation(pszIconfile, iIconindex);
        }

        /* Use the IPersistFile object to save the shell link */
        hRes = pShellLink->QueryInterface(
          IID_IPersistFile,         /* pre-defined interface of the 
                                        IPersistFile object */
          (LPVOID*)&pPersistFile);            /* returns a pointer to the 
                                        IPersistFile object */
        if (SUCCEEDED(hRes))
        {
          iWideCharsWritten = MultiByteToWideChar(CP_ACP, 0, 
                                               pszLinkfile, -1,
                                               wszLinkfile, MAX_PATH);
          hRes = pPersistFile->Save(wszLinkfile, TRUE);
          pPersistFile->Release();
        }
        pShellLink->Release();
      }

    }
    CoUninitialize();
    return (hRes);
}

Comments

3

This MSDN artice, Shell Links, provide a comprehensive tutorial about the subject with code example.

1 Comment

This is amusing, the link you provided and the link that Paul provided are the same page, but they have physically different links. I wonder why that is. Just odd. Just wanted to throw that out there.
-2

You can use system function to execute mklink command.

system("mklink /d shortcut_name Target_file");

4 Comments

This will not create a shortcut (lnk file)
but some other combinations, like /J for linking directories do.
/d is for a link to a directory; just remove /d for a link to a file
The mklink tool creates hard/soft links at the filesystem level. This is not at all related to creating *.lnk files, or the shell.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.