How do I create desktop shortcuts from C++?

F5cf0fba9ba5e628b2131836b42d3a14
0
Spudman 101 Oct 09, 2006 at 13:44

How can I create a desktop shortcut from a C++ program on Windows XP ?
- I can’t seem to find anything on this in the DevStudio help…
Cheers

13 Replies

Please log in or register to post a reply.

F5cf0fba9ba5e628b2131836b42d3a14
0
Spudman 101 Oct 09, 2006 at 14:23

Thanks…

F5cf0fba9ba5e628b2131836b42d3a14
0
Spudman 101 Oct 11, 2006 at 11:00

Thanks for the info about how to create a desktop shortcut. I used the code from the link you sent but
the ‘IPersistFile::Save’ method always returns an
error -9, ie. permission denied.. I’ve tried several
different paths to save the shortcut, but it won’t
have it…. I’m not a .com programmer so It’s probably something silly I’m doing (or not doing…)
Any ideas gratefully applied….
Thanks

340bf64ac6abda6e40f7e860279823cb
0
_oisyn 101 Oct 11, 2006 at 12:01

Do you have some code? My guess is that perhaps you are using wrong slashes in the path (‘/’ instead of ‘\’) or that you forgot to escape the backslashes (c:\foo\bar becomes “c:\\foo\\bar” in C++)

46407cc1bdfbd2db4f6e8876d74f990a
0
Kenneth_Gorking 101 Oct 11, 2006 at 13:49

Or maybe you are not logged in with administrator privileges :)

340bf64ac6abda6e40f7e860279823cb
0
_oisyn 101 Oct 11, 2006 at 15:40

Surely you don’t have to have administrator privileges to create shortcuts on the desktop?

But my previous post is moot btw, you won’t get ‘permission denied’ errors when using a wrong path, I wasn’t thinking.

46407cc1bdfbd2db4f6e8876d74f990a
0
Kenneth_Gorking 101 Oct 11, 2006 at 23:57

I wasn’t thinking either it would seem. I have been having privileges issues lately, so now I see them everywhere :)

Try sticking a ‘hres = ppf->SaveCompleted(wsz);’ between the Save and Release.

6b7e1a4b42e4b47d92fdef8bf2bd8e2c
0
Jare 101 Oct 11, 2006 at 23:58

@.oisyn

Surely you don’t have to have administrator privileges to create shortcuts on the desktop?

There’s the “all users” desktop and the “current user” desktop, I suppose.

340bf64ac6abda6e40f7e860279823cb
0
_oisyn 101 Oct 12, 2006 at 00:34

Right, that makes sense. And the “default user” desktop (the template for new user accounts).
So Spudman, which path are you using, and where are you getting it from?
SHGetFolderPath(0, CSIDL_DESKTOPDIRECTORY, 0, 0, pMyPath) should do the trick, where pMyPath is a char[MAX_PATH] buffer receiving the path. Note that using CSIDL_DESKTOP as folder id, or a -1 as the access token (3rd parameter), would both likely result in the permission denied error you’re getting.

F5cf0fba9ba5e628b2131836b42d3a14
0
Spudman 101 Oct 13, 2006 at 09:57

Thanks for the feedback, I’ve tried the above suggestions but to no avail..
The path and descript passed to:

psl->SetPath(lpszPathObj);
psl->SetDescription(lpszDesc);

lpszPathObj is C:\testDir\testApp.exe
lpszDesc is temp1 shortcut

Still stumped…
but here’s the source code…

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

hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER,
IID_IShellLink, (LPVOID*)&psl);
if (SUCCEEDED(hres))
{

IPersistFile* ppf;

psl->SetPath(lpszPathObj);
psl->SetDescription(lpszDesc);

hres = psl->QueryInterface(IID_IPersistFile, (LPVOID*)&ppf);

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

SHGetFolderPath(0, CSIDL_DESKTOPDIRECTORY, 0, 0, pMyPath);

MultiByteToWideChar(CP_ACP, 0, pMyPath, -1, wsz, MAX_PATH);

hres = ppf->Save(wsz, TRUE);
hres = ppf->SaveCompleted(wsz);
ppf->Release();
}
psl->Release();
}
return hres;
}

46407cc1bdfbd2db4f6e8876d74f990a
0
Kenneth_Gorking 101 Oct 13, 2006 at 14:16

Figured it out! The path to provide to IPersist::Save needs to include to filename of the shortcut too, not just a path. This of course makes sense when you think about it. Insert this:

wcscat(wsz, L"\\");
wcscat(wsz, L"Shortcut.lnk");

…after the call to MultiByteToWideChar.
Also be sure to use double backslashes to the path object, so it becomes C:\\testDir\\testApp.exe.

Happy shortcutting :)

P.S. the SaveCompleted() call is not needed.

F5cf0fba9ba5e628b2131836b42d3a14
0
Spudman 101 Oct 13, 2006 at 16:30

Yes!!! - Thanks Kenneth Gorking - this works… yippee!.
Eternally grateful etc…
:yes:

340bf64ac6abda6e40f7e860279823cb
0
_oisyn 101 Oct 13, 2006 at 16:48

Like, duh, of course you need a filename in the path ;)