Jump to content


How do I create desktop shortcuts from C++?


13 replies to this topic

#1 Spudman

    Member

  • Members
  • PipPip
  • 38 posts

Posted 09 October 2006 - 01:44 PM

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

#2 .oisyn

    DevMaster Staff

  • Moderators
  • 1842 posts

Posted 09 October 2006 - 02:06 PM

Via the IShellLink interface (yes, that's COM)
http://msdn.microsof...ts/shortcut.asp
C++ addict
-
Currently working on: the 3D engine for Tomb Raider.

#3 Spudman

    Member

  • Members
  • PipPip
  • 38 posts

Posted 09 October 2006 - 02:23 PM

Thanks...

#4 Spudman

    Member

  • Members
  • PipPip
  • 38 posts

Posted 11 October 2006 - 11:00 AM

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

#5 .oisyn

    DevMaster Staff

  • Moderators
  • 1842 posts

Posted 11 October 2006 - 12:01 PM

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++)
C++ addict
-
Currently working on: the 3D engine for Tomb Raider.

#6 Kenneth Gorking

    Senior Member

  • Members
  • PipPipPipPip
  • 939 posts

Posted 11 October 2006 - 01:49 PM

Or maybe you are not logged in with administrator privileges :)
"Stupid bug! You go squish now!!" - Homer Simpson

#7 .oisyn

    DevMaster Staff

  • Moderators
  • 1842 posts

Posted 11 October 2006 - 03:40 PM

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.
C++ addict
-
Currently working on: the 3D engine for Tomb Raider.

#8 Kenneth Gorking

    Senior Member

  • Members
  • PipPipPipPip
  • 939 posts

Posted 11 October 2006 - 11:57 PM

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.
"Stupid bug! You go squish now!!" - Homer Simpson

#9 Jare

    Valued Member

  • Members
  • PipPipPip
  • 247 posts

Posted 11 October 2006 - 11:58 PM

.oisyn said:

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.

#10 .oisyn

    DevMaster Staff

  • Moderators
  • 1842 posts

Posted 12 October 2006 - 12:34 AM

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.
C++ addict
-
Currently working on: the 3D engine for Tomb Raider.

#11 Spudman

    Member

  • Members
  • PipPip
  • 38 posts

Posted 13 October 2006 - 09:57 AM

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;
}

#12 Kenneth Gorking

    Senior Member

  • Members
  • PipPipPipPip
  • 939 posts

Posted 13 October 2006 - 02:16 PM

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.
"Stupid bug! You go squish now!!" - Homer Simpson

#13 Spudman

    Member

  • Members
  • PipPip
  • 38 posts

Posted 13 October 2006 - 04:30 PM

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

#14 .oisyn

    DevMaster Staff

  • Moderators
  • 1842 posts

Posted 13 October 2006 - 04:48 PM

Like, duh, of course you need a filename in the path ;)
C++ addict
-
Currently working on: the 3D engine for Tomb Raider.





1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users