|
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;
}
| You must Sign In to use this message board. |
|
| | Msgs 1 to 25 of 31 (Total in Forum: 31) (Refresh) | FirstPrevNext |
|
 |
|
|
Code causes problems - application hangs, after function ResolveLink call. Parameters SLR_ANY_MATCH | SLR_NO_UI | SLR_UPDATE were added in psl->Resolve.
Here modification in function ResolveLink:
... hres = ppf->Load(LnkFile, STGM_READ); if (SUCCEEDED(hres)) { hres = psl->Resolve(GetDesktopWindow(), SLR_ANY_MATCH | SLR_NO_UI | SLR_UPDATE);
...
BR, Rudi.
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
Hi..All.. what is A2W converter, how it is used. why we write USING_CONVERSION, before using convertors. Thanq..
sheshidar
|
| Sign In·View Thread·PermaLink | 2.00/5 (2 votes) |
|
|
|
 |
|
|
It gave me unresolved external g_pfnGetThreadACP under VS2005. Including atlbase.h solved the problem.
|
| Sign In·View Thread·PermaLink | 5.00/5 (1 vote) |
|
|
|
 |
|
|
thx =)
- thomasa88
-- modified at 19:11 Monday 26th June, 2006
Im not very good on c++ compile flags, how should they be set for vs 2005? Right now I just changed /MT to /MD
|
| Sign In·View Thread·PermaLink | 1.80/5 (2 votes) |
|
|
|
 |
|
|
I've tried to use the lib in the following way:
//Creating a shortcut ShortCut sc = new ShortCut(); sc.FilePath = "http://google.dk"; sc.LnkPath = "c:\\a b c.lnk"; sc.LnkDesc = "This runs notepad"; sc.WorkDir = "C:\\"; sc.CreateLink();
//Resolving a shortcut sc.LnkPath = "C:\\a b c.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);
The link is successfully created, and is working fine with an http address, but when you try to resolve it, the filepath is empty?
The documentaion for IShellLink don't say anything about http links, do anybody have a clue?
I'm using the lib in relation to Explorer favorites and there for i need to work with http links.
Troels Richter Thinksharp.dk
|
| Sign In·View Thread·PermaLink | 2.00/5 (1 vote) |
|
|
|
 |
|
|
Hello Nish,
i want to use this great feature, but my intend ist to avoid the distribution of more than one file (the .exe file). In this case i can't generate a .dll and ship them along with the .exe.
Now the question: Is there a chance to get the contents of the library in c# instead of c++? In this case i can copy the source directly into my project (visual studio .net) and compile it.
thx in advance
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
 |
|
|
I would use this class too, if there was an "iconpath" property that allowed me to specify the path to the icon for the shortcut.
|
| Sign In·View Thread·PermaLink | 2.00/5 (1 vote) |
|
|
|
 |
|
|
 |
|
|
I downloaded the shortcut project and compiled it, and referenced the dll using C#.
It is working perfectly. Excellant work, you have saved me time.
Also I liked your approach, as you used C++ to write the utility, in my opinion this is the best way to implement shortcuts for .NET languages.
Have a great week!
Russell Mangel Las Vegas, NV
Russell Mangel Las Vegas, NV
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
 |
|
|
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 
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
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
 |
|
|
 |
|
|
I think this code is very useful. The only problem is that I have no idea if the shortcut file is created or not.
Eg.
sc.FilePath = filename; .... sc.CreateLink();
// Then manually check if the link has been created
if (!File.Exists(filename)) { // Inform the user the shortcut was not created }
I thought it may be better to return a value / throw an exception when the actual shortcut is not created.
Matt
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
 |
|
|
 |
|
|
 |
|
|
Hey Nish,
I think you have a lot of fans here. I realized that your first two ratings are two 1s. There are some guys here who love you (I think).
I dont know what their problem is but it is for sure that you deserve much better ratings.
Mustafa Demirhan http://www.macroangel.com Sonork ID 100.9935:zoltrix
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
Mustafa Demirhan wrote: I think you have a lot of fans here. I realized that your first two ratings are two 1s. There are some guys here who love you (I think).
I dont know what their problem is but it is for sure that you deserve much better ratings.
Hello Mustafa,
It's been a while since I saw you. And you are not on Sonork [zoltrix] too these days.
Yeah, this article seems to have displeased a few 
Nish
Regards, Nish Native CPian. Born and brought up on CP. With the CP blood in him.
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
Nish [BusterBoy] wrote: It's been a while since I saw you. And you are not on Sonork [zoltrix] too these days.
Unfortunately! I can rarely find some time to visit CodeProject. But things will be better in a week. My final exams will end this week.
Mustafa Demirhan http://www.macroangel.com Sonork ID 100.9935:zoltrix
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
Good luck with your examinations 
Nish
Regards, Nish Native CPian. Born and brought up on CP. With the CP blood in him.
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
Instead of using Marhsal.CoTaskMemAlloc etc. (in your case) You can very easily convert String* to wchar_t* using PtrToStringChars function. this is defined in vcclr.h
Note that in that case you don't need to Free the memory.
King of Managed C++
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
Thanks King of MC++. I saw that function, but I felt it has the same dangers associated with CString::GetBuffer
Nish
Regards, Nish Native CPian. Born and brought up on CP. With the CP blood in him.
|
| Sign In·View Thread·PermaLink | 2.00/5 (1 vote) |
|
|
|
 |
|
|
I donno what's causing the whole article to scroll horizontally 
Regards Nish
p.s. I am also confused by the bad-indentation within the code blocks. The indentation was okay in the Article Wizard Preview. But now it seems slightly messed up
Regards, Nish Native CPian. Born and brought up on CP. With the CP blood in him.
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
General News Question Answer Joke Rant Admin
|