Click here to Skip to main content
Click here to Skip to main content

Creating and Resolving shell links

, 10 May 2002
Rate this:
Please Sign up or sign in to vote.
An MC++ class that uses IJW to invoke the IShellLink interface
<!-- Download Links -->

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#]

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

Share

About the Author

Nish Nishant

United States United States
Nish Nishant is a Software Architect/Consultant based out of Columbus, Ohio. He has over 15 years of software industry experience in various roles including Lead Software Architect, Principal Software Engineer, and Product Manager. Nish is a recipient of the annual Microsoft Visual C++ MVP Award since 2002 (13 consecutive awards as of 2014).

Nish is an industry acknowledged expert in the Microsoft technology stack. He authored
C++/CLI in Action for Manning Publications in 2005, and had previously 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 vastly experienced in team management, mentoring teams, and directing all stages of software development.

Contact Nish : You can reach Nish on his google email id voidnish.

Website and Blog

Comments and Discussions

 
GeneralCPP ShortCut Source PinmemberRussell Mangel15-Oct-03 17:42 
GeneralRe: CPP ShortCut Source PinstaffNishant S15-Oct-03 18:42 
GeneralAccess is denied: 'ShortCut' Pinmemberw3home11-Apr-03 1:03 
I tried to use your code, by adding a reference to the DLL,
but i get an error message when compiling my project (called TestPictures)

The strange thing is that i get no error messages when adding the reference in my project. The DLL is located in My InetPub/wwwroot/bin directory. I also checked the properties of the DLL (ok for read and execute), but still that doesn't work Frown | :(

Can you please help me on that point ?

The message i get is the following one :

Server Error in '/TestPictures' Application.
-------------------------------------------------------------------

Access is denied: 'ShortCut'.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: System.IO.FileLoadException: Access is denied: 'ShortCut'.

Source Error:

An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.




Assembly Load Trace: The following information can be helpful to determine why the assembly 'ShortCut' could not be loaded.


=== Pre-bind state information ===
LOG: DisplayName = ShortCut, Version=1.0.1196.18153, Culture=neutral, PublicKeyToken=null
(Fully-specified)
LOG: Appbase = file:///c:/inetpub/wwwroot/TestPictures
LOG: Initial PrivatePath = bin
Calling assembly : TestPictures, Version=1.0.1196.19450, Culture=neutral, PublicKeyToken=null.
===

LOG: Policy not being applied to reference at this time (private, custom, partial, or location-based assembly bind).
LOG: Post-policy reference: ShortCut, Version=1.0.1196.18153, Culture=neutral, PublicKeyToken=null
LOG: Attempting download of new URL file:///C:/WINDOWS/Microsoft.NET/Framework/v1.1.4322/Temporary ASP.NET Files/testpictures/06cd0ac2/161adc7/ShortCut.DLL.
LOG: Attempting download of new URL file:///C:/WINDOWS/Microsoft.NET/Framework/v1.1.4322/Temporary ASP.NET Files/testpictures/06cd0ac2/161adc7/ShortCut/ShortCut.DLL.
LOG: Attempting download of new URL file:///c:/inetpub/wwwroot/TestPictures/bin/ShortCut.DLL.



Stack Trace:

[FileLoadException: Access is denied: 'ShortCut'.]
TestPictures.WebForm3.Page_Load(Object sender, EventArgs e) +0
System.Web.UI.Control.OnLoad(EventArgs e) +67
System.Web.UI.Control.LoadRecursive() +35
System.Web.UI.Page.ProcessRequestMain() +731




Johanna
GeneralRe: Access is denied: 'ShortCut' PineditorNishant S13-Apr-03 10:03 
GeneralRe: Access is denied: 'ShortCut' PinmemberMarco Morreale30-Jun-03 3:19 
GeneralShortcut file not created Pinmemberschmiddy25-Mar-03 18:20 
GeneralRe: Shortcut file not created PineditorNishant S25-Mar-03 19:05 
GeneralRe: Shortcut file not created PinsussAnonymous25-Mar-03 19:12 
GeneralRe: Shortcut file not created PineditorNishant S25-Mar-03 19:14 
GeneralFans! PinmemberMustafa Demirhan11-May-02 15:11 
GeneralRe: Fans! PinmemberNish [BusterBoy]11-May-02 15:19 
GeneralRe: Fans! PinmemberMustafa Demirhan11-May-02 15:24 
GeneralRe: Fans! PinmemberNish [BusterBoy]11-May-02 15:36 
GeneralUse PtrToStringChars PinmemberMCPPKing11-May-02 6:39 
GeneralRe: Use PtrToStringChars PinmemberNish [BusterBoy]11-May-02 6:38 
GeneralSorry about the horizontal scrolling! And the messy indentation. PinmemberNish [BusterBoy]11-May-02 5:40 
GeneralRe: Sorry about the horizontal scrolling! And the messy indentation. PinmemberShog911-May-02 6:55 
GeneralRe: Sorry about the horizontal scrolling! And the messy indentation. PinmemberNish [BusterBoy]11-May-02 7:34 
GeneralRe: Sorry about the horizontal scrolling! And the messy indentation. PineditorAndrew Peace11-May-02 14:03 
GeneralRe: Sorry about the horizontal scrolling! And the messy indentation. PinmemberNish [BusterBoy]11-May-02 15:12 
GeneralRe: Sorry about the horizontal scrolling! And the messy indentation. PinsubeditorMichael Dunn11-May-02 13:23 
GeneralRe: Sorry about the horizontal scrolling! And the messy indentation. PinmemberNish [BusterBoy]11-May-02 15:14 

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
Web04 | 2.8.150414.1 | Last Updated 11 May 2002
Article Copyright 2002 by Nish Nishant
Everything else Copyright © CodeProject, 1999-2015
Layout: fixed | fluid