How to add icons on the desktop during a setup process

MSelect used Ask the Experts™
Using the standard setup program of VB6 and customizing Setup1.exe, a shortcut is always created by default in the Start/program menu.
I want to add also icons in the "Quick start" bar and on the desktop.
There is no problem to add an icon in the "Quick start" bar with this code :

OSfCreateShellLink "..\..\APPLIC~1\MICROS~1\INTERN~1\QUICKL~1",strProgramIconTitle, strProgramPath, strProgramArgs, fPrivate, sParent

because the folder exists in any Windows language.

Nevertheless, if I try to replace
it doesn't work because the name of this path depends on the local language
for example, it's "Bureau" in french, and not "Desktop" ...
Is there a function to get this folder name under any circumstances in order to pass it then to
the function ?

Thank you,
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®

Yes, you can use SHGetFolderLocation Win32 API

This function is enable in Windows 2000 and Windows ME

For Windows 95 or later, you can use SHGetSpecialFolderLocation instead
Ensure you’re charging the right price for your IT

Do you wonder if your IT business is truly profitable or if you should raise your prices? Learn how to calculate your overhead burden using our free interactive tool and use it to determine the right price for your IT services. Start calculating Now!


Thank you but ...
Neither SHGetSpecialFolderLocation nor SHGetFolderLocation can be found among the available function declarations ...
Might you give me the exact declaration and some explanation about the probable constants to use ?

In addition, is SHGetSpecialFolderLocation still available in Win Me too or must I write something like
If "WIn ME" then "SHGetFolderLocation" ... else "SHGetSpecialFolderLocation"


Thank you for your help but ...
Why doesn't it work ???
I get the right path (i.e the "Desktop") to install the link but OSfCreateShellLink doesn't create it !

Const CSIDL_COMMON_DESKTOPDIRECTORY& = &H19 'All Users\Desktop : it's for Win NT or 2000

Private Declare Function SHGetPathFromIDList& Lib "shell32" Alias "SHGetPathFromIDListA" (ByVal pidl&, ByVal pszPath$)
Private Declare Function SHGetSpecialFolderLocation& Lib "shell32" (ByVal hwndOwner&, ByVal nFolder&, pidl&)
Private Declare Sub CoTaskMemFree Lib "ole32" (ByVal pv&)
Private Declare Function OSfCreateShellLink& Lib "vb6stkit.dll" Alias "fCreateShellLink" (ByVal FolderName$, ByVal LinkName$, ByVal LinkPath$, ByVal LinkArguments$, ByVal fPrivate&, ByVal sParent$)

Private Sub Command1_Click()
   Dim xPath$, result&, MyApp$, IconTitle$
   MyApp = "C:\MyFolder\MyApp.exe"
   IconTitle = "SomeText"
   xPath = GetSpecialFolderLocation()
  'xPath = "C:\Windows\Bureau"   OK
   result = OSfCreateShellLink(xPath, IconTitle, MyApp, "", 0, "")
  'result = 0   ??????
End Sub

Private Function GetSpecialFolderLocation$()
   Dim TXT$, pidl&  
   SHGetSpecialFolderLocation Me.hWnd, CSIDL_DESKTOP, pidl
   If pidl <> 0 Then
      TXT = Space$(255)
      If SHGetPathFromIDList(ByVal pidl, ByVal TXT) Then GetSpecialFolderLocation = Left$(TXT, InStr(TXT, Chr$(0)) - 1)
      CoTaskMemFree pidl
    End If
End Function


I have code which I myself has used in a commercial product with VB5:

Option Explicit

' // Shell File Operations

Global Const gstrQUOTE$ = """"

Public Const FO_MOVE = &H1
Public Const FO_COPY = &H2
Public Const FO_RENAME = &H4
Public Const FO_DELETE = &H3
Public Const FOF_SILENT = &H4                      '  don't create progress/report

        hwnd As Long
        wFunc As Long
        pFrom As String
        pTo As String
        fFlags As Integer
        fAnyOperationsAborted As Long
        hNameMappings As Long
        lpszProgressTitle As String '  only used if FOF_SIMPLEPROGRESS
End Type

Declare Function GetWindowsDirectory Lib "kernel32" Alias "GetWindowsDirectoryA" (ByVal lpBuffer As String, ByVal nSize As Long) As Long
Declare Function GetDesktopWindow Lib "user32" () As Long
Declare Function SHFileOperation Lib "shell32" (lpfileop As SHFILEOPSTRUCT) As Long
Declare Function GetOSFolder Lib "hvstrlib.dll" (ByVal id As Long, s As String) As Integer
Declare Function OSfCreateShellLink Lib "VB5STKIT.DLL" Alias "fCreateShellLink" (ByVal lpstrFolderName As String, ByVal lpstrLinkName As String, ByVal lpstrLinkPath As String, ByVal lpstrLinkArguments As String) As Long
Declare Function OSfRemoveShellLink Lib "VB5STKIT.DLL" Alias "fRemoveShellLink" (ByVal lpstrFolderName As String, ByVal lpstrLinkName As String) As Long

Public Function strUnQuoteString(ByVal strQuotedString As String)
    strQuotedString = Trim(strQuotedString)
    If Mid$(strQuotedString, 1, 1) = gstrQUOTE And Right$(strQuotedString, 1) = gstrQUOTE Then
        strQuotedString = Mid$(strQuotedString, 2, Len(strQuotedString) - 2)
    End If
    strUnQuoteString = strQuotedString
End Function

Function GetDeskTopPath() As String
  Dim desk As String
  Dim i%, j%, k%
  On Error GoTo 1
  desk = String(255, vbNullChar)
  i = GetOSFolder(&H10, desk)
  desk = left(desk, i)
  k = 0
  i = 1
    j = InStr(i, desk, "\")
    If j <> 0 Then k = j
    i = j + 1
  Loop While j <> 0
  desk = "..\.." + Mid(desk, k)
  GetDeskTopPath = desk
  Exit Function
  GetDeskTopPath = ""

End Function

Function CopyLink(prgpath As String, desk As String, lnkname As String) As Boolean
  CopyLink = XCreateShellLink(prgpath + prgName, desk, "", lnkname) 'prgName is the target exe
End Function

Function XCreateShellLink(ByVal strLinkPath As String, ByVal strGroupName As String, ByVal strLinkArguments As String, ByVal strLinkName As String) As Boolean
  On Error GoTo 1
  strLinkName = strUnQuoteString(strLinkName)
  strLinkPath = strUnQuoteString(strLinkPath)
  XCreateShellLink = OSfCreateShellLink(strGroupName & "", strLinkName, strLinkPath, strLinkArguments & "")
  Exit Function
  XCreateShellLink = False
End Function

You use it kinda like this:

dim dtop as string
dim apps as string

dtop = GetDeskTopPath
apps = RemoveBackslash(App.path)
CopyLink(apps, dtop, "My link")

Code for RemoveBackslash:

Function RemoveBackslash(path As String) As String
  If Right(path, 1) = "\" Then
    RemoveBackslash = left(path, Len(path) - 1)
    RemoveBackslash = path
  End If
End Function
GetOSFolder is your GetSpecialFolderLocation but written in C:

#include <shlobj.h>

short int GetOSFolder(int type,BSTR *s)
     HWND handle;
     LPSTR lpstr[MAX_PATH];
     HRESULT ret;

     handle = GetDesktopWindow();
     ret = SHGetSpecialFolderLocation(handle,type,&ppidl);
     if (SHGetPathFromIDList(ppidl,(char *) lpstr) == TRUE) {
          SysReAllocString (s,(BSTR) lpstr);
       return strlen((char *) lpstr);
     return 0;


points for all the elements you gave.

You should give points only if my solution satifies your needs. But I won't complain. Thanks.

your code works to with some modification. Don't ask me why.

 Dim fprivate As Long
 Dim sparent As String
 fprivate = 0
 sparent = ""
  result = OSfCreateShellLink(xPath, IconTitle, MyApp, "", fprivate, sparent)


Evidently, why must 0 and "" be stored in variables before being sent to the function ??????
A new mystery ! I don't ask you why :-)

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial