by Richard Russell, June 2007
If you want to create a shortcut (link) to a file or a folder, you can do it using the PROCshortcut routine listed below. You would call the routine using code similar to the following:
PROCshortcut("C:\Documents and Settings\RTR\Desktop\Test Shortcut.lnk", \ \ "C:\Program Files\BBC BASIC for Windows\bbcwin.exe", \ \ "C:\Program Files\BBC BASIC for Windows\Examples\", \ \ "Test shortcut created by BBC BASIC for Windows")
The first parameter is the path and filename of the shortcut to be created; it must have the extension “.lnk”.
The second parameter is the target of the shortcut; it can be the name of a file or the path to a folder.
The third parameter specifies the working directory, if the shortcut refers to an executable program.
The fourth parameter is a comment describing the shortcut.
Of course you should ideally not specify the locations of the shortcut and files using explicit paths, such as shown above, but instead determine the correct locations using the FNspecialfolder() function from the main Help documentation:
CSIDL_DESKTOPDIRECTORY = 16 CSIDL_PROGRAM_FILES = 38 link$ = FNspecialfolder(CSIDL_DESKTOPDIRECTORY) + "Test Shortcut.lnk" target$ = FNspecialfolder(CSIDL_PROGRAM_FILES) + "BBC BASIC for Windows\bbcwin.exe" start$ = FNspecialfolder(CSIDL_PROGRAM_FILES) + "BBC BASIC for Windows\Examples\" PROCshortcut(link$, target$, start$, "Test shortcut created by BBC BASIC")
To make the shortcut available to all users rather than just the current user change CSIDL_DESKTOPDIRECTORY to CSIDL_COMMON_DESKTOPDIRECTORY.
Here is the PROCshortcut routine itself:
REM PROCshortcut - uses the Shell's IShellLink and IPersistFile interfaces REM to create and store a shortcut to the specified object. REM REM Parameters: REM LinkFile$ - the path/filename of the shortcut (.LNK) REM Target$ - the object for which to create a shortcut REM StartIn$ - the working directory to start in REM Comment$ - the description of the shortcut DEF PROCshortcut(LinkFile$, Target$, StartIn$, Comment$) LOCAL ole32%, clsid%, iidsl%, iidpf%, wsz%, psl%, ppf%, psl{}, ppf{} DIM clsid% LOCAL 15, iidsl% LOCAL 15, iidpf% LOCAL 15 DIM wsz% LOCAL 2*LEN(LinkFile$)+1 DIM psl{QueryInterface%, AddRef%, Release%, GetPath%, GetIDList%, SetIDList%, \ \ GetDescription%, SetDescription%, GetWorkingDirectory%, \ \ SetWorkingDirectory%, GetArguments%, SetArguments%, \ \ GetHotkey%, SetHotkey%, GetShowCmd%, SetShowCmd%, GetIconLocation%, \ \ SetIconLocation%, SetRelativePath%, Resolve%, SetPath%} DIM ppf{QueryInterface%, AddRef%, Release%, GetClassID%, IsDirty%, \ \ Load%, Save%, SaveCompleted%, GetCurFile%} SYS "LoadLibrary", "OLE32.DLL" TO ole32% SYS "GetProcAddress", ole32%, "CoInitialize" TO `CoInitialize` SYS "GetProcAddress", ole32%, "CoUninitialize" TO `CoUninitialize` SYS "GetProcAddress", ole32%, "CoCreateInstance" TO `CoCreateInstance` SYS `CoInitialize`, 0 clsid%!0 = &00021401 : REM CLSID_ShellLink clsid%!4 = &00000000 clsid%!8 = &000000C0 clsid%!12 = &46000000 iidsl%!0 = &000214EE : REM IID_IShellLink iidsl%!4 = &00000000 iidsl%!8 = &000000C0 iidsl%!12 = &46000000 iidpf%!0 = &0000010B : REM IID_IPersistFile iidpf%!4 = &00000000 iidpf%!8 = &000000C0 iidpf%!12 = &46000000 REM Get a pointer to the IShellLink interface: _CLSCTX_INPROC_SERVER = 1 SYS `CoCreateInstance`, clsid%, 0, _CLSCTX_INPROC_SERVER, iidsl%, ^psl% IF psl% = 0 ERROR 100, "Cannot create IShellLink interface" !(^psl{}+4) = !psl% REM Set the target object, working directory and comment: SYS psl.SetPath%, psl%, Target$ SYS psl.SetWorkingDirectory%, psl%, StartIn$ SYS psl.SetDescription%, psl%, Comment$ REM Query IShellLink for the IPersistFile interface: SYS psl.QueryInterface%, psl%, iidpf%, ^ppf% IF ppf% = 0 ERROR 100, "Cannot create IPersistFile interface" !(^ppf{}+4) = !ppf% REM Convert the path string to Unicode: SYS "MultiByteToWideChar", 0, 0, LinkFile$, -1, wsz%, LEN(LinkFile$)+1 REM Save the link by calling IPersistFile::Save: SYS ppf.Save%, ppf%, wsz%, 1 REM Tidy up: SYS ppf.Release%, ppf% SYS psl.Release%, psl% SYS `CoUninitialize` ENDPROC
For information about how to read (dereference) a short cut see the article on reading a shortcut.