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();
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:
#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);
}
};
}
#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;
}