Creating a Windows shortcut in a special folder
By: Lorenzo Dalla Vecchia  Date: 17/09/2001

With reference to the Creating a Windows shortcut tip, the procedure of creating a Windows "link" to a file involves the use of the fCreateShellLink API function, whose declaration is the following:

Declare Function fCreateShellLink Lib "VB5STKIT.DLL" ( _
ByVal lpstrFolderName As String, ByVal lpstrLinkName As String, _
ByVal lpstrLinkPath As String, _

ByVal lpstrLinkArgs As String) As Long

The syntax is pretty simple:

x = fCreateShellLink("folder", "link title", "path", "args")

"link title", "path" and "args" are, respectively, the caption of the shortcut, the path it points to and the command-line arguments for the file. For "folder" you may enter any valid path of a physical folder or "..\..\Desktop" for the Desktop.
But what to do if you want to put the link, say, in the Start Menu or Favorites?

These folders are called "special" because they have a particular representation and use that make them different from "regular" folders. However, behind most of them there is a real physical folder. The problem is that the real path is often unknown and may differ in the different localized versions of Windows: for example the real path of the Start Menu in the English version of Windows is C:\Windows\Start Menu, while in the Italian version is C:\Windows\Menu Avvio. Additionaly, the path of the Windows folder itself may differ.

All we need is a function that can unveil the real location of special folders. These functions are called SHGetSpecialFolderLocation and SHGetPathFromIDList. Their declarations are:

Declare Function SHGetSpecialFolderLocation Lib "shell32.dll" _
(ByVal hwndOwner As Long, ByVal nFolder As Long, _
pidl As ITEMIDLIST) As Long
Declare Function SHGetPathFromIDList Lib "shell32.dll" _

Alias "SHGetPathFromIDListA" (ByVal pidl As Long, _
ByVal pszPath As String) As Long
Type
SHITEMID
   
cb As Long
   
abID As Byte
End Type
Type
ITEMIDLIST
   
mkid As SHITEMID
End Type

After you have put the declarations in a module, cut and paste the following function to let them work:

Private Function FindSpecialFolder(ID As Long) As String
    Dim RetVal As Long
    Dim ItemList As ITEMIDLIST

    Dim PathBuff As String
    RetVal = SHGetSpecialFolderLocation(100, ID, ItemList)
    If RetVal = 0 Then
        PathBuff = Space(512)
        RetVal = SHGetPathFromIDList(ByVal ItemList.mkid.cb, ByVal PathBuff)
        FindSpecialFolder = Left(PathBuff, InStr(PathBuff, Chr(0)) - 1)
        Exit Function
    End If
    FindSpecialFolder = ""
End Function

The last thing you need is a list of constants to tell the function what folder to retrieve.
You don't need them all, just copy in the Declartions section the constants you need for your program:

Const CSIDL_DESKTOP = &H0
Const CSIDL_PROGRAMS = &H2
Const CSIDL_PERSONAL = &H5
Const CSIDL_FAVORITES = &H6
Const CSIDL_STARTUP = &H7
Const CSIDL_RECENT = &H8
Const CSIDL_SENDTO = &H9
Const CSIDL_STARTMENU = &HB
Const CSIDL_DESKTOPDIRECTORY = &H10
Const CSIDL_NETHOOD = &H13
Const CSIDL_FONTS = &H14
Const CSIDL_TEMPLATES = &H15

Now, time for some examples.
The code to put a link in the Start Menu Programs group, would be:

Dim x As Long
x = fCreateShellLink(FindSpecialFolder(CSIDL_PROGRAMS), _
"My Link", "C:\MyFolder\Program.Exe", "")

The code to put a link in the Startup group (to let the link start each time Windows starts), would be:

Dim x As Long
x = fCreateShellLink(FindSpecialFolder(CSIDL_STARTUP), _
"My Link", "C:\MyFolder\Program.Exe", "")

And so on.

Click Here!


Visual Basic Programming Zone is a website by Lorenzo Dalla Vecchia.
To contact the Webmaster, click here.
Hosted by InWind: www.inwind.it