Click here to Skip to main content
15,860,972 members
Articles / Programming Languages / C++/CLI
Article

Creating and Resolving shell links

Rate me:
Please Sign up or sign in to vote.
4.92/5 (19 votes)
10 May 2002 261.5K   1.4K   27   33
An MC++ class that uses IJW to invoke the IShellLink interface

Introduction

ShortCut is a .NET class that allows you to create shortcuts to files as well as resolve existing shortcuts. The class was coded in Managed C++ and makes ample use of IJW. I have compiled the class as a Class Library under the namespace ShortCutLib. Thus you can now use it from your C# and VB .NET programs. Simply add a reference to the DLL. This is yet another example of how Managed C++ eases the transition between managed and unmanaged code so easily. It just works!

Sample Usage [C#]

C#
using System;
using ShortCutLib;

namespace ShortCutTest
{
    class Class1
    {
        [STAThread]
        static void Main(string[] args)
        {
            ShortCut sc = new ShortCut();

            //Creating a shortcut
            sc.FilePath = "C:\\windows\\notepad.exe";
            sc.LnkPath = "c:\\abc.lnk";
            sc.LnkDesc = "This runs notepad";
            sc.WorkDir = "C:\\";
            sc.CreateLink();

            //Resolving a shortcut
            sc.LnkPath = "C:\\xyz.lnk";
            sc.ResolveLink();

            Console.WriteLine("File is {0}",sc.FilePath);
            Console.WriteLine("Description is {0}",sc.LnkDesc);
            Console.WriteLine("Woirking Dir is {0}",sc.WorkDir);
        }
    }
}

Source Listing (only the main header and cpp file)

For those of you who only have beta 2, you can use the following two source listings:

// ShortCut.h

#pragma once

using namespace System;
using namespace System::Runtime::InteropServices;

namespace ShortCutLib
{
    public __gc class ShortCut
    {
        private:
            String* m_filepath;
            String* m_workdir;
            String* m_lnkdesc;
            String* m_lnkpath;

            HRESULT _CreateLink(LPCWSTR FilePath, LPCWSTR LnkPath, 
                                LPCWSTR LnkDesc,LPCWSTR WorkDir);
            HRESULT _ResolveLink(LPCWSTR LnkFile, LPWSTR FilePath,
                                 LPWSTR LnkDesc,LPWSTR WorkDir);

        public:     
            __property String* get_FilePath()
            {
                return m_filepath;
            }
            __property void set_FilePath(String *str)
            {
                m_filepath = str;
            }
            __property String* get_WorkDir()
            {
                return m_workdir;
            }
            __property void set_WorkDir(String *str)
            {
                m_workdir = str;
            }
            __property String* get_LnkDesc()
            {
                return m_lnkdesc;
            }
            __property void set_LnkDesc(String *str)
            {
                m_lnkdesc = str;
            }
            __property String* get_LnkPath()
            {
                return m_lnkpath;
            }
            __property void set_LnkPath(String *str)
            {
                m_lnkpath = str;
            }
                
            bool CreateLink()
            {
                IntPtr strfilepath = Marshal::StringToCoTaskMemUni(FilePath);
                IntPtr strlnkpath = Marshal::StringToCoTaskMemUni(LnkPath);
                IntPtr strlnkdesc = Marshal::StringToCoTaskMemUni(LnkDesc);
                IntPtr strworkdir = Marshal::StringToCoTaskMemUni(WorkDir);
                
                HRESULT hres = _CreateLink((LPCWSTR)strfilepath.ToPointer(),
                                           (LPCWSTR)strlnkpath.ToPointer(),
                                           (LPCWSTR)strlnkdesc.ToPointer(),
                                           (LPCWSTR)strworkdir.ToPointer());

                Marshal::FreeCoTaskMem(strfilepath);
                Marshal::FreeCoTaskMem(strlnkpath);
                Marshal::FreeCoTaskMem(strlnkdesc);
                Marshal::FreeCoTaskMem(strworkdir);

                return (hres==S_OK);
            }

            bool ResolveLink()
            {
                wchar_t strfilepath[MAX_PATH];
                wchar_t strworkdir[MAX_PATH];
                wchar_t strlnkdesc[INFOTIPSIZE];

                IntPtr strlnkpath = Marshal::StringToCoTaskMemUni(LnkPath);         
                
                HRESULT hres = _ResolveLink((LPCWSTR)strlnkpath.ToPointer(),
                    strfilepath, strlnkdesc, strworkdir);

                FilePath = strfilepath;
                LnkDesc = strlnkdesc;
                WorkDir = strworkdir;
                    
                Marshal::FreeCoTaskMem(strlnkpath);         

                return (hres==S_OK);
            }
    };
}
// This is the main DLL file.

#include "stdafx.h"
#using <mscorlib.dll>
#include <Shlobj.h>
#include <crtdbg.h>
#include <atldef.h>
#include <atlconv.h>

#include "ShortCut.h"


HRESULT ShortCutLib::ShortCut::_CreateLink(LPCWSTR FilePath, 
    LPCWSTR LnkPath, LPCWSTR LnkDesc,LPCWSTR WorkDir) 
{ 
    USES_CONVERSION;
    CoInitialize(NULL);
    IShellLink* psl;             
    HRESULT  hres = CoCreateInstance(CLSID_ShellLink, NULL, 
            CLSCTX_INPROC_SERVER, IID_IShellLink, (LPVOID *) &psl); 
    if (SUCCEEDED(hres)) 
    { 
        IPersistFile* ppf; 
         
        psl->SetPath(W2A(FilePath)); 
        psl->SetWorkingDirectory(W2A(WorkDir));
        psl->SetDescription(W2A(LnkDesc)); 
            
        hres = psl->QueryInterface(IID_IPersistFile,(LPVOID*)&ppf); 
 
        if (SUCCEEDED(hres)) 
        {    
            hres = ppf->Save(LnkPath, TRUE); 
            ppf->Release(); 
        } 
        psl->Release(); 
    }
    CoUninitialize();
    return hres; 
} 

HRESULT ShortCutLib::ShortCut::_ResolveLink(LPCWSTR LnkFile, LPWSTR FilePath,
                                            LPWSTR LnkDesc,LPWSTR WorkDir) 
{ 
    CoInitialize(NULL);
    HRESULT hres; 
    IShellLink* psl; 
    WIN32_FIND_DATA wfd; 
    char strfilepath[MAX_PATH];     
    char strlnkdesc[INFOTIPSIZE];
    char strworkdir[MAX_PATH];

    USES_CONVERSION;
 
    hres = CoCreateInstance(CLSID_ShellLink, NULL, 
            CLSCTX_INPROC_SERVER, IID_IShellLink, (LPVOID *) &psl); 
    if (SUCCEEDED(hres)) 
    { 
        IPersistFile* ppf;         
        hres = psl->QueryInterface(IID_IPersistFile, (LPVOID *)&ppf); 
        if (SUCCEEDED(hres)) 
        { 
            hres = ppf->Load(LnkFile, STGM_READ); 
            if (SUCCEEDED(hres)) 
            {               
                hres = psl->Resolve(GetDesktopWindow(), 0); 
                if (SUCCEEDED(hres)) 
                { 
                    hres = psl->GetPath(strfilepath,MAX_PATH, &wfd, 
                                           SLGP_UNCPRIORITY );
                    
                    if (SUCCEEDED(hres)) 
                    {            
                        wcscpy(FilePath, A2W(strfilepath)); 
                        hres = psl->GetDescription(strlnkdesc,INFOTIPSIZE);
                    }

                    if (SUCCEEDED(hres)) 
                    {
                        wcscpy(LnkDesc,A2W(strlnkdesc));
                        hres = psl->GetWorkingDirectory(strworkdir,MAX_PATH);
                    }

                    if (SUCCEEDED(hres)) 
                    {
                        wcscpy(WorkDir,A2W(strworkdir));
                    }
                } 
            }         
            ppf->Release(); 
        }     
        psl->Release(); 
    } 
    CoUninitialize();
    return hres; 
} 

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
United States United States
Nish Nishant is a technology enthusiast from Columbus, Ohio. He has over 20 years of software industry experience in various roles including Chief Technology Officer, Senior Solution Architect, Lead Software Architect, Principal Software Engineer, and Engineering/Architecture Team Leader. Nish is a 14-time recipient of the Microsoft Visual C++ MVP Award.

Nish authored C++/CLI in Action for Manning Publications in 2005, and co-authored Extending MFC Applications with the .NET Framework for Addison Wesley in 2003. In addition, he has over 140 published technology articles on CodeProject.com and another 250+ blog articles on his WordPress blog. Nish is experienced in technology leadership, solution architecture, software architecture, cloud development (AWS and Azure), REST services, software engineering best practices, CI/CD, mentoring, and directing all stages of software development.

Nish's Technology Blog : voidnish.wordpress.com

Comments and Discussions

 
Generalrunning under 64 bit OS? Pin
Thomas Ramaglia7-Jun-11 11:04
Thomas Ramaglia7-Jun-11 11:04 
QuestionWhat about LNK to installed app (not pointed to exe, created by MSI) Pin
JnZ7321-May-09 3:34
JnZ7321-May-09 3:34 
GeneralCorrection Pin
Member 74870021-May-08 21:51
Member 74870021-May-08 21:51 
GeneralA2W conversion Pin
sheshidar27-Jul-06 19:50
sheshidar27-Jul-06 19:50 
GeneralLinking under VS2005 Pin
marad0124-May-06 4:43
marad0124-May-06 4:43 
GeneralRe: Linking under VS2005 [modified] Pin
thomasa88_26-Jun-06 12:51
thomasa88_26-Jun-06 12:51 
QuestionShortcutLib can't handle http links? Pin
dommer16-Feb-05 9:25
dommer16-Feb-05 9:25 
QuestionIs there a chance to get the library in native c# code? Pin
rleins3-Jun-04 3:06
rleins3-Jun-04 3:06 
AnswerRe: Is there a chance to get the library in native c# code? Pin
Nish Nishant3-Jun-04 3:52
sitebuilderNish Nishant3-Jun-04 3:52 
GeneralGreat Code, but where is the &quot;iconpath&quot; property Pin
softcell6-Mar-04 2:13
softcell6-Mar-04 2:13 
GeneralCreate MSI Links Pin
Anonymous20-Oct-03 1:50
Anonymous20-Oct-03 1:50 
I want to create MSI Links on the Desktop. Is there a solution?

Thanks
Matthias
GeneralCPP ShortCut Source Pin
Russell Mangel15-Oct-03 16:42
Russell Mangel15-Oct-03 16:42 
GeneralRe: CPP ShortCut Source Pin
Nish Nishant15-Oct-03 17:42
sitebuilderNish Nishant15-Oct-03 17:42 
GeneralAccess is denied: 'ShortCut' Pin
w3home11-Apr-03 0:03
w3home11-Apr-03 0:03 
GeneralRe: Access is denied: 'ShortCut' Pin
Nish Nishant13-Apr-03 9:03
sitebuilderNish Nishant13-Apr-03 9:03 
GeneralRe: Access is denied: 'ShortCut' Pin
Member 40724430-Jun-03 2:19
Member 40724430-Jun-03 2:19 
GeneralShortcut file not created Pin
schmiddy25-Mar-03 17:20
schmiddy25-Mar-03 17:20 
GeneralRe: Shortcut file not created Pin
Nish Nishant25-Mar-03 18:05
sitebuilderNish Nishant25-Mar-03 18:05 
GeneralRe: Shortcut file not created Pin
Anonymous25-Mar-03 18:12
Anonymous25-Mar-03 18:12 
GeneralRe: Shortcut file not created Pin
Nish Nishant25-Mar-03 18:14
sitebuilderNish Nishant25-Mar-03 18:14 
GeneralFans! Pin
Mustafa Demirhan11-May-02 14:11
Mustafa Demirhan11-May-02 14:11 
GeneralRe: Fans! Pin
Nish Nishant11-May-02 14:19
sitebuilderNish Nishant11-May-02 14:19 
GeneralRe: Fans! Pin
Mustafa Demirhan11-May-02 14:24
Mustafa Demirhan11-May-02 14:24 
GeneralRe: Fans! Pin
Nish Nishant11-May-02 14:36
sitebuilderNish Nishant11-May-02 14:36 
GeneralUse PtrToStringChars Pin
11-May-02 5:39
suss11-May-02 5:39 

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

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