Results 1 to 12 of 12

Thread: [RESOLVED] Creating shortcuts without using Script Host Object

  1. #1

    Thread Starter
    Fanatic Member
    Join Date
    Jan 2006
    Posts
    557

    Resolved [RESOLVED] Creating shortcuts without using Script Host Object

    I am creating shortcuts on the Desktop using the Script Host Object. It all works fine, but I would like to free my applications from the wshom.ocx reference. Searching the net did not yield other interesting results. I peaked at the .lnk file format, but it's rather involved, and if I did write a proper .lnk, I bet there would be other surprises down the line.

    Is there any other API way of creating a shortcut? One of my requirements is being able to specify an icon in addition of a target path. Thanks.

  2. #2
    PowerPoster dilettante's Avatar
    Join Date
    Feb 2006
    Posts
    24,487

    Re: Creating shortcuts without using Script Host Object

    Well you could "go to the source" and do this via Shell Automation. It's another wrapper on Shell's flat API calls much as you've been using but at least it is all housed in the same library (Shell32.dll).

    Code:
    Option Explicit
    
    Private Sub CreateLink()
        Const ssfDESKTOP As Long = 0
        Dim F As Integer
    
        With CreateObject("Shell.Application").NameSpace(ssfDESKTOP)
            'Create new (empty) link, here we'll do it on the Desktop:
            F = FreeFile(0)
            Open .Self.Path & "\Sample.lnk" For Binary Access Write As #F
            Close #F
    
            'Populate link data, update:
            With .Items.Item("Sample.lnk").GetLink
                .Path = App.Path & "\" & App.EXEName & ".exe"
                .WorkingDirectory = App.Path
                .Arguments = "Hello World!"
                .Description = App.FileDescription
                .ShowCommand = 1
                .SetIconLocation .Path, 0
                .Save
            End With
        End With
    End Sub
    
    Private Sub Main()
        If Len(Command$()) > 0 Then
            MsgBox Command$()
        Else
            On Error Resume Next
            GetAttr App.EXEName & ".exe"
            If Err Then
                MsgBox "Compile this program first."
                Exit Sub
            End If
            On Error GoTo 0
    
            'Create a "shortcut" to myself on the Desktop:
            CreateLink
        End If
    End Sub
    Attached Files Attached Files

  3. #3
    PowerPoster
    Join Date
    Feb 2012
    Location
    West Virginia
    Posts
    14,206

    Re: Creating shortcuts without using Script Host Object

    Another option is to use the method that the package and deployment wizard uses. The source code is included with VB6. It uses I think the vb6stkit.dll

    Code:
    Public Declare Function OSfCreateShellLink Lib "vb6stkit.dll" Alias "fCreateShellLink" (ByVal lpstrFolderName As String, ByVal lpstrLinkName As String, ByVal lpstrLinkPath As String, ByVal lpstrLinkArguments As String, ByVal fPrivate As Long, ByVal sParent As String) As Long
    Last edited by DataMiser; Oct 14th, 2014 at 06:12 PM.

  4. #4
    PowerPoster
    Join Date
    Jun 2013
    Posts
    7,454

    Re: Creating shortcuts without using Script Host Object

    For completeness (and to introduce a Helper-Object, which can also set e.g. the
    "Run as Administrator"-flag, in case that's needed)...

    Here's what it looks like when vbRichClient5.cShellLink is used:

    Code:
    Private Sub Main()
    Dim WorkDir As String
      WorkDir = New_c.FSO.GetUserAppDataPath & "\MyApp\"
      If Not New_c.FSO.FolderExists(WorkDir) Then New_c.FSO.CreateDirectory WorkDir
      
      With New_c.ShellLink
        .SetWorkingDirectory WorkDir
        .SetPath "Notepad.exe"
    '    .SetArguments "SomeTextFile.txt" 'set arguments if needed here
        .SetDescription "This starts Notepad.exe"
        .SetHotKey (vbCtrlMask Or vbAltMask) * 256 + vbKeyN 'use Ctrl+Alt+N as a HotKey
        .SetShowCmd SL_SHOWNORMAL
        
        'not setting the IconLocation will use the default-icon of the executable or document...
        'alternatively force the *.lnk to use either an Icon from a Dll-Resource, or from an *.ico-File
    '    .SetIconLocation "shell32.dll", 80
    '    .SetIconLocation "C:\MyIcons\SomeIcon.ico", 0
        
        'comment the next line in, if you want to switch-on the "Run as Administrator"-Flag
    '    .SetFlags SLDF_RUNAS_USER
    
        'the last line below finally writes out the *.lnk-File to the Desktop
        .Save New_c.FSO.GetSpecialFolder(CSIDL_DESKTOPDIRECTORY) & "\MyLink.lnk", True
      End With
    End Sub
    Olaf

  5. #5
    PowerPoster
    Join Date
    Jul 2010
    Location
    NYC
    Posts
    7,654

    Re: Creating shortcuts without using Script Host Object

    VBRichClient5 is a bit of overkill; you can gain access to IShellLink by itself...

    http://www.vbaccelerator.com/home/VB...onstration.asp is a heavyweight demonstration,

    but the core routine can be simplified into just one function once the typelib is added as a reference...

    Code:
    Public Sub SaveNewLink(sLink As String, _
                           sPath As String, _
                           Optional sIconFile As String = vbNullString, _
                           Optional ByVal lIcon As Long = 0, _
                           Optional ByVal iHK As Integer = 0, _
                           Optional sArgs As String = vbNullString, _
                           Optional sDesc As String = vbNullString, _
                           Optional ByVal pidl As Long = 0, _
                           Optional sWorkDir As String = vbNullString, _
                           Optional sRelPath As String = vbNullString, _
                           Optional swc As EShowWindowFlags = SW_NORMAL)
    Dim csl As CShellLink
    Dim ipf As IPersistFileVB
    
    Set csl = New CShellLink
    Set ipf = csl
    With csl
        .SetPath (sPath)
        .SetArguments sArgs
        .SetDescription sDesc
        .SetIconLocation sIconFile, lIcon
        .Hotkey = iHK
        .ShowCmd = swc
        .SetRelativePath sRelPath, 0
        .SetWorkingDirectory sWorkDir
        If pidl Then .SetIDList pidl
        
        .Resolve 0, SLR_UPDATE
        
    End With
    
    ipf.Save sLink, 0
    
    Set ipf = Nothing
    Set csl = Nothing
    A lot of projects already have olelib.tlb as a reference, which does contain the IShellLink interface... I can't recall the problem that made me switch to VBAccelerator's lib...

    Edit: In olelib there's no coclass for it so you can't use the New statement. It can be patched with
    Code:
    [ uuid(00021401-0000-0000-C000-000000000046),
       helpstring("VB IShellLinkA Class")
    ]
    coclass ShellLinkA {
       [default] interface IShellLinkA;
    };
    if you were so inclined. I only mention this because olelib is common, but many things aren't done right, so then you start getting multiple versions of interfaces and have to start always remembering you want ShellLinkVB.IShellLink and not olelib.IShellLink, etc. So it's better to update olelib.
    Last edited by fafalone; Oct 14th, 2014 at 11:28 PM.

  6. #6

    Thread Starter
    Fanatic Member
    Join Date
    Jan 2006
    Posts
    557

    Re: Creating shortcuts without using Script Host Object

    Thank you everyone, I did not expect solutions that varied in scope.

    I will try everyone of them, actually I have already, some with mixed results. In each one of them there is something to learn but ultimately, my basic criteria are :

    - as simple as possible, with as little dependencies as possible, especially for the project i need the feature for.
    - must be able to work with modern Icon formats, not the outdated icons insertable in a VB6 compiled exe.


    Dilettante :

    Your little project worked fine, simple with only calls to shell32.dll. I am running into a little glitch trying to customize it. A medium long report would be needed here. I'll keep that for later, after I have done a bit more work.


    Datamiser :

    that one was easy, thanks ... just a little bit short though on external icon support.


    Olaf :

    elegant, very short piece of code, looks real good. For a while I thought it was the File Scripting Object (scrrun.dll).. is it ? No such method as GetUserAppDataPath in scripting object. I am obviouly working with the wrong object...
    vbRichClient5 ?? i could not find that, code did not work.

    fafalone :

    Thanks, Interesting code... reasonably compact... i had no problem getting the tlb from vbAccelerator, but the parameters described here lack clarity of documentation. I wanted to give a peak at the bigger project, but it would not load and let me peak at the code without going back there a third time and get some ocx not included in the project. I once had a plan to rework the Icon Program on vbAccelerator. The guy there writes code that is hard to manage. I had to let go this one for the time being at least.

  7. #7
    Hyperactive Member
    Join Date
    Jul 2013
    Posts
    402

    Re: Creating shortcuts without using Script Host Object

    Navion, just search for vbRichClient with google. It seems that posting the link is forbidden, don't try to understand

  8. #8
    PowerPoster
    Join Date
    Jun 2013
    Posts
    7,454

    Re: Creating shortcuts without using Script Host Object

    Quote Originally Posted by Navion View Post
    Olaf :

    elegant, very short piece of code, looks real good. For a while I thought it was the File Scripting Object (scrrun.dll).. is it ? No such method as GetUserAppDataPath in scripting object. I am obviouly working with the wrong object...
    vbRichClient5 ?? i could not find that, code did not work.
    vbRichClient5 is a free available, modern Framework for VB5/6 which contains a lot of
    useful Helper-Classes - many of them without alternative in the VBClassic-universe.

    The above New_c.FSO instance of the RichClient is not using the Scripting.FSO under the hood,
    it's a Wrapper-Class around a lot of FileSystem-APIs - and Unicode-capable throughout
    (the whole RichClient-functionality is unicode-aware).

    E.g. cFSO offers beside "the usual File-Functions and -Dialogs" also FileSystem-Watchers, the
    fastest DirListing-class available for VB6, and maybe interesting for you, also a (huge-file-capable)
    Stream-Class, a fast CSV-parser for CSV-files > 4GB, Unicode-Reading/Decoding etc.

    It contains also the fastest XML-parser for VB6, the fastest JSON-parser for VB6, the
    fastest Collection and Dictionary-Classes for VB6, the fastest (ADO-like usable) COM-wrapper
    for SQLite, and the most complete and comprehensive graphics- and GUI-framework for VB6
    (easier and with larger functionality than GDI+, as e.g. offering SVG-support and PDF-support).

    It will add about 1.6MB (when LZMA-compressed, 2.2MB when zipped) deployment-size to an Application,
    but on the other hand allows "regfree usage and shipping" in a SubFolder alongside your App, so these
    "costs" are very bearable I'd think.

    Other than e.g. on the vbAccelerator-site (which offers a lot of separated, but related binaries), the
    Class-Stack in the RichClient is "precompiled and bundled in one place" - and major version-numbers
    try to maintain binary-compatibility on the COM-interfaces.

    I wrote it as a modern ClassRuntime-Enhancement for VBClassic - available for anybody...
    just check in a single project-reference, and then "off you go" with kinda like a "VB 6.5".

    Olaf
    Last edited by Schmidt; Oct 15th, 2014 at 07:19 AM.

  9. #9
    PowerPoster
    Join Date
    Jul 2010
    Location
    NYC
    Posts
    7,654

    Re: Creating shortcuts without using Script Host Object

    Quote Originally Posted by Navion View Post
    Thanks, Interesting code... reasonably compact... i had no problem getting the tlb from vbAccelerator, but the parameters described here lack clarity of documentation. I wanted to give a peak at the bigger project, but it would not load and let me peak at the code without going back there a third time and get some ocx not included in the project. I once had a plan to rework the Icon Program on vbAccelerator. The guy there writes code that is hard to manage. I had to let go this one for the time being at least.
    You don't have to worry about any of the code. All you have to do is add the vba TLB as a reference (you don't also need olelib; that's a whole other topic i was talking about), then the single function I posted will create the shortcut. No other code needed.
    sLink - the full output link, e.g. c:\path\file.txt.lnk
    sPath - the full path of the input file, e.g. c:\file.txt
    sIconFile As String - It uses the default icon on its own, but you can manually change it by specifying the file with the new icon here
    lIcon - And the index/ID of the icon here
    iHK - define a hotkey... not sure myself never used it
    sArgs - the 'arguments' box of shortcut properties; blank unless you need command line arguments for an exe
    sDesc - Specify your own description
    pidl - Instead of a filename, you can use a fully qualified pidl (ignore this if you don't know what that is)
    sWorkDir - Working directory; almost never needed
    sRelPath - Use a relative path; rarely used
    EShowWindowFlags - normal, windowed, maximized, etc.

    All the Optional arguments can be ignored if you're not using them; you can make it as simple as SaveNewLink("C:\file.txt.lnk", "C:\folder\file.txt")
    Last edited by fafalone; Oct 15th, 2014 at 07:29 AM.

  10. #10

    Thread Starter
    Fanatic Member
    Join Date
    Jan 2006
    Posts
    557

    Re: Creating shortcuts without using Script Host Object

    Quote Originally Posted by Schmidt View Post
    vbRichClient5 is a free available, modern Framework for VB5/6 which contains a lot of
    useful Helper-Classes - many of them without alternative in the VBClassic-universe.
    Ok, thanks, got it now.. Interesting project whose goal I do embrace. I downloaded it. Will give it a closer look soon.

  11. #11

    Thread Starter
    Fanatic Member
    Join Date
    Jan 2006
    Posts
    557

    Re: Creating shortcuts without using Script Host Object

    Quote Originally Posted by fafalone View Post
    You don't have to worry about any of the code. All you have to do is add the vba TLB as a reference (you don't also need olelib; that's a whole other topic i was talking about), then the single function I posted will create the shortcut. No other code needed.
    sLink - the full output link, e.g. c:\path\file.txt.lnk
    sPath - the full path of the input file, e.g. c:\file.txt
    Yeahh.. that's what I thought, simple enough, but it did not work, hence my comment about documentation. I was really exhausted at the time I tried it. I had put an exit sub in the routine to check the passing of arguments before calling a routine that writes to my precious desktop. Forgot to remove it. My bad. I spotted this first thing this morning. Works A-OK.

    (Edit) Details about the project :

    It is a super tiny program that contains half a dozen most needed file, clipboard and desktop management utilities. Compiled just once, it performs self installation, creation of shortcuts on the desktop and/or taskbar. The program is designed as a drop in folder, with no external system dependencies whatsoever. All Windows versions contain the basic VB6 runtime files, but as soon as you add an external control or dll or OCX, you have to provide a package to install and register those dependencies. I wanted to alleviate that. Once compiled, the main exe is just copied with different names as 6 different utilities and each behaves according to its EXE name.

    With your routine, I could reduce the setup code to these two lines (it could have been one)

    Code:
    apptoken$ = App.EXEName
    SaveNewLink makeFilename(desktopFolder, apptoken$ & ".lnk"), makeFilename(App.Path, apptoken$ & ".exe"), makeFilename(App.Path, apptoken$ & ".ico")
    Actually, this is not exactly what I am using, there is a little bit more code checking file existence, whether or not shortcuts have been installed in the task bar, etc.. but essentially, those two lines perform all the setup work. Come to think of it will probably move the file checking code inside the SaveNewLink routine (and call it CheckLinks).
    Last edited by Navion; Oct 15th, 2014 at 09:50 AM. Reason: more details

  12. #12

    Thread Starter
    Fanatic Member
    Join Date
    Jan 2006
    Posts
    557

    Re: [RESOLVED] Creating shortcuts without using Script Host Object

    Thanks everyone. Solution tested and deployed from XP to 10, no dependencies ;

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width