# VBForums CodeBank > CodeBank - Visual Basic 6 and earlier >  Change Shortcut Properties/Icon

## RobDog888

I put this example together to demonstrate how to programmatically access a shortcut in 
the Program Files Start Menu. With variations of this code you can gain access to any property of a 
shortcut. I hope members enjoy this code and post replies of what you think of it.

This demo will change the properties for Internet Explorer in your Start Menu > Program Files.
Comments: the tooltip and comment description for the link.
Arguments: it wil add an argument to the shortcut target.
ShowCommand: it will set the window show state to Maximized
SetIconLocation: it will change the location of the icon to use and designate the icon index to use.
Save: Saves the changes to the shortcut.
InvokeVerb: runs the open command (optionally by uncomenting the line of code)






VB Code:
Option Explicit
'References:
'Microsoft Shell Controls And Automation '(C:\Windows\System32\Shell32.dll)
 'ShowCommand Constants
'1 Activates and restores it to its original size and position.
'2 Activates the window and displays it as a minimized window.
'3 Activates the window and displays it as a maximized window.
Private Const ssfSYSTEM = 37             'System32 directory
Private Const ssfPROGRAMS = 2            'Program Files
Private Const ssfDESKTOP = 0
Private Const ssfDESKTOPDIRECTORY = 16
Private Const ssfDRIVES = 17
Private Const ssfPERSONAL = 5            'My Documents folder
Private Const ssfCOMMONDESKTOPDIR = 25
Private Const ssfWINDOWS = 36            'Windows or Winnt directory
 Private Sub Command1_Click()
'Original Comment: Finds and displays information and Web sites on the Internet.
'Original Argument: "" 'Uses your default home page setting. Replace arg with where you want IE to go to when opened
'Original ShowCommand: 1
'Original Icon Path: "C:\Program Files\Internet Explorer\IEXPLORE.EXE" - For my system, yours would be where ever you have IE installed to.
'Original Icon Index:
'Test Icon Path: "C:\Windows\System32\SHELL32.dll"
'Test Icon Index: 46 - Windows Update Icon
    Dim oShell  As Shell32.Shell
    Dim oFolder As Shell32.Folder
    
    Set oShell = New Shell32.Shell
    Set oFolder = oShell.NameSpace(ssfPROGRAMS)
        If (Not oFolder Is Nothing) Then
            Dim oFolderItem As Shell32.FolderItem
            Set oFolderItem = oFolder.ParseName("Internet Explorer.lnk")
            If (Not oFolderItem Is Nothing) Then
                Dim oShellLink As ShellLinkObject
                Set oShellLink = oFolderItem.GetLink
                If (Not oShellLink Is Nothing) Then
                    'Set the arguments for the ShellLinkObject
                    oShellLink.Arguments = "http://www.vbforums.com"
                    oShellLink.Description = "This text is added to the comments of the link programmatically."
                    oShellLink.ShowCommand = 3
                    oShellLink.SetIconLocation "C:\Windows\System32\SHELL32.dll", 46 'Windows Update Icon
                    oShellLink.Save
                    'oFolderItem.InvokeVerb "open" 'Opens IE and navigates to VBF !
                End If
                Set oShellLink = Nothing
            End If
            Set oFolderItem = Nothing
        End If
    Set oFolder = Nothing
    Set oShell = Nothing
    
End Sub

----------


## |2eM!x

im confused..how does it know what shortcut to shell?

i dont want it to shell my vb exe, but a shortcut..

edit** nvm i think, i get this error..
    Dim oShell  As Shell32.Shell
    Dim oFolder As Shell32.Folder
"user defined type not defined"

----------


## RobDog888

You need to add the reference to 'Microsoft Shell Controls And Automation 
(C:\Windows\System32\Shell32.dll) to your project so it knows how Shell32 is defined.

Also, the constants are how you can determine where your link is located. 

The ssfPROGRAMS constant tells the program that the link is going to be in 
the Program Files Start Menu. I havent got it all down yet but it would be 
nice to get it to work for desktop shortcut creation/modification.

----------


## |2eM!x

shoot, thats what im doing..
("..\..\Desktop")
does that work?

----------


## RobDog888

The const is either ssfDESKTOP or ssfDESKTOPDIRECTORY.
But I havent 
got it to work for that yet either, only the Program Files Start Menu.

----------


## |2eM!x

when you do, report back : )

also, how do you find out what can be read by the dll?
i.e, how did you find the ssfdesktop command??

or how do you tell what dll does what..

----------


## RobDog888

In the Object Browser (press F2) it will allow you to browse through the 
object referenced in your project. The const.'s seem to follow the CLSID_ ...
constants for other functions like the SHBrowseForFolder API.

----------


## |2eM!x

you ever figure it out bro?

----------


## RobDog888

No, I havent had time. I've been writting another CodeBank entry and a few 
examples for some members. Plus working on my .NET Control. Perhaps we should 
start another thread? This thread is just for code examples.  :Wink:

----------


## |2eM!x

when you do, pm me

----------


## RobDog888

I'll post back here so you will get notification. 

You want to modify it to change a Desktop Shortcut Icon

----------


## BodwadUK

Extra Notes

You can change to search a specific directory by changing


VB Code:
Set oFolder = oShell.NameSpace(ssfPROGRAMS)
 TO If you want c drive root
 Set oFolder = oShell.NameSpace("c:\")


You may also find the values on the link useful for none fixed windows folders
http://msdn.microsoft.com/library/de...rconstants.asp


Hope that helps everyone   :Big Grin:

----------


## RobDog888

Thanks for the link but I got the consts from the clsid's from the SHGetSpecialFolderLocation API. 
Nice tip on the .Namespace  :Thumb:  Maybe I will get inspired to do more on this then.

----------


## sciguyryan

Is there any way using a simmilar method, to create a shortcut to a program?

Cheers,

RyanJ

----------


## RobDog888

Yes, you can use this example to create a shortcut. It uses WSH.

Create shortcut

----------


## sciguyryan

> Yes, you can use this example to create a shortcut. It uses WSH.
> 
> Create shortcut



Great, thanks RobDog888  :Smilie: 

Cheers,

RyanJ

----------


## RobDog888

Ok, this update is for Remix. I figured out the issue of not being able to attach to the Desktop. Turns out that you can not use the .ParseName function on virtual directories. Since the Program Files Start Menu is a file system directory it works but on the Desktop virtual directory it fails with a return of Nothing.

Enjoy the update guys.  :Big Grin: 

VB Code:
Option Explicit
'References:
'Microsoft Shell Controls And Automation '(C:\Windows\System32\Shell32.dll)
 Private Const ssfSYSTEM = 37             'System32 directory
Private Const ssfPROGRAMS = 2            'Program Files
Private Const ssfDESKTOP = 0
Private Const ssfDESKTOPDIRECTORY = 16   'Your profile desktop
Private Const ssfDRIVES = 17
Private Const ssfPERSONAL = 5            'My Documents folder
Private Const ssfCOMMONDESKTOPDIR = 25
Private Const ssfWINDOWS = 36            'Windows or Winnt directory
 Private Sub Command1_Click()
     Dim oShell  As Shell32.Shell
    Dim oFolder As Shell32.Folder
    
    Set oShell = New Shell32.Shell
    Set oFolder = oShell.NameSpace(ssfDESKTOPDIRECTORY)
        If (Not oFolder Is Nothing) Then
            Dim oFolderItem As Shell32.FolderItem
            Dim i As Integer
            Dim bFound As Boolean
            For i = 1 To oFolder.Items.Count
                If oFolder.Items.Item(i) = "Test.lnk" Then
                    Set oFolderItem = oFolder.Items.Item(i)
                    bFound = True
                    Exit For
                End If
            Next
            If bFound = False Then Exit Sub
            If (Not oFolderItem Is Nothing) Then
                Dim oShellLink As ShellLinkObject
                Set oShellLink = oFolderItem.GetLink
                If (Not oShellLink Is Nothing) Then
                    MsgBox oShellLink.Path & " " & oShellLink.Arguments
                End If
                Set oShellLink = Nothing
            End If
            Set oFolderItem = Nothing
        End If
    Set oFolder = Nothing
    Set oShell = Nothing
    
End Sub

----------


## Fazi

Thanks rob...

Seems a big thread. I ll check it ...

----------


## Navarone

I realize this is an old tread but I have a question as I am trying to use it in my application. I have an icon on my desktop called "Agent Prospecting Presentation", I want to chnage the target path from this:

C:\MyWestfieldPresentation\Westfield_1to1F.exe
to this:
C:\MyWestfieldPresentation\Westfield_1to1F_v1.exe

Everything else in icon properties can stay the same.

I tried using the code but I couldn't get the target path to changes. What am I doing wrong?


VB Code:
Dim oShell  As Shell32.shell
    Dim oFolder As Shell32.Folder
    
    Set oShell = New Shell32.shell
    Set oFolder = oShell.NameSpace(ssfDESKTOPDIRECTORY)
        If (Not oFolder Is Nothing) Then
            Dim oFolderItem As Shell32.FolderItem
            Dim i As Integer
            Dim bFound As Boolean
            For i = 1 To oFolder.Items.Count
                If oFolder.Items.Item(i) = "\Agent Prospecting Presentation.lnk" Then
                    Set oFolderItem = oFolder.Items.Item(i)
                    bFound = True
                    Exit For
                End If
            Next
            If bFound = False Then Exit Sub
            If (Not oFolderItem Is Nothing) Then
                Dim oShellLink As ShellLinkObject
                Set oShellLink = oFolderItem.GetLink
                If (Not oShellLink Is Nothing) Then
                    'MsgBox oShellLink.Path & " " & oShellLink.Arguments
                    'Set the arguments for the ShellLinkObject
                    oShellLink.Arguments = "C:\MyWestfieldPresentation\Westfield_1to1F_v1.exe"
                    oShellLink.Description = "This was changed 06092006."
                    oShellLink.ShowCommand = 2
                    oShellLink.SetIconLocation "C:\WestfieldInsurance\Westfield_1to1F_v1.exe", 46 'Windows Update Icon
                    oShellLink.Save
                 End If
                Set oShellLink = Nothing
            End If
            Set oFolderItem = Nothing
        End If
    Set oFolder = Nothing
    Set oShell = Nothing

----------


## RobDog888

You would want to use the oShellLink.Path instead as the .Arguments is for passing arguments to the target program.


Who said it was old?  :Big Grin:

----------


## Navarone

So, all I need to do is replace the arguments line with the path line like this?


VB Code:
oShellLink.Path = "C:\MyWestfieldPresentation\Westfield_1to1F_v1.exe"

----------


## Navarone

I am still not able to get this to work. I think the problem is that the shortcut is located in the "AllUsersDesktop" folder. I am not sure what to use for the oShell.NameSpace().

Any thoughts?

----------


## RobDog888

Use the ssfCOMMONDESKTOPDIR constant then.



VB Code:
ssfCOMMONDESKTOPDIR = 0x19

----------


## zenoaghaz

Is there any way using a API, to create or resolve a shortcut without creating shell object? please only use API .
thanks for help me   :wave:

----------


## RobDog888

Welcome to the Forums.

Yes, there are a couple but does not look as easy to use as the shell object. It shows as not being supported so not sute how to use or if its for desltop shortcuts or hyperlink browser shortcuts.

VB Code:
Private Declare Sub HlinkResolveShortcut Lib "hlink.dll" (ByVal pwzShortcutFileName As String, ByRef pihlsite As Long, _
ByVal dwSiteData As Long, ByVal piunkOuter As Long, ByVal riid As Long, ByRef ppvObj As Any)
 Private Declare Sub HlinkCreateShortcut Lib "hlink.dll" (ByVal grfHLSHORTCUTF As Long, ByRef pihl As Long, ByVal pwzDir As String, _
ByVal pwzFileName As String, ByVal ppwzShortcutFile As String, ByVal dwReserved As Long)

http://windowssdk.msdn.microsoft.com.../ms538245.aspx

----------


## Birra

Hey there   :wave:  . I hope no one minds me bumping a thread from 2 months ago. I adapted this code for myself and it worked great, so thanks.

But one thing i was wondering about is it's only compatible with .lnk shortcuts. While oFolderItem.IsLink will return true for both a .lnk and a .pif, it is only compatible with .lnk's.

So when oFolderItem is equal to a .pif file, (take for example "Aladdin.pif"), it crashes at the code "oShellLink = oFolderItem.GetLink", telling me that it could not find the specified file.

(Even though my profile says .NET 2002 it's based on this code so vb6 code is fine)


Just to fill you's in about the program i'm making, It's called shortcutter. Given a "Game Folders" directory (a folder in which there are folders for every game inside) and a "Shortcut Destination" directory, it finds all the executables for any game in that folder (one game at a time), and accurately predicts which is the main game executable (and if you click accept, or you can choose a different executable from the listview), it creates a shortcut for you. This way you can make shortcuts to abt 50 games in under a minute, so i find it quite useful.

So what i am trying to get it to do now is, at the user's choice, ignore making shortcuts for games that already have one in the "Shortcut Destination" directory.

But yeah, half of them are shortcuts to dos games which presents a problem.
So does anyone know how to make this code compatible with .pif's?

Thanks in advance

----------


## RobDog888

Welcome to the Forums.

No prob posting to the thread as this is where you would want to post.  :Wink: 

A pif file is an old format. Why do you need pif support? The Shell32 library will not work with pif files. They will need to be handled differently.

----------


## Birra

Just because i still like some of the old platform games, and shortcuts to those games become Pifs. See my folder structure is that all my games are installed to C:\Games\Files & a shortcut to every game is in C:\Games. I like it that way.

But yeah that's why. I was afraid you might say that, about shell32 not supporting pifs. Well if you can point me to where i could find something that might help please let me know.

I've thought about it and i'm going to be directing most dos games through dosbox now, which is a win32 app so i probably wont have many .pifs at all after i do that (except for the ones i can't get to work properly in there), so it might not matter so much afterall.

But thanx for any help   :Wink: 

[Just editing this to make it clearer. In order to ignore previously made shortcuts, it needs to read the target paths of every shortcut file in the "shortcut destination" directory, so that it can compare those paths to the game executables it finds so it know's when to skip. That's when pifs come into it. But like i said, may not matter so much and thanks for any help   :Smilie:  )

----------


## RobDog888

Here are a few links on pifs and how to make them etc.
As the article states, its a no-no to interface directly with DOS. Going through something like dosbox would be much better.

http://support.microsoft.com/kb/q131877/
http://filext.com/detaillist.php?extdetail=PIF
http://www.cknow.com/ckinfo/p/PIF-Pr...mationFil.html

----------


## Birra

okay thanks. I guess i'll just pass as parameters to dosbox. thanx for your help  :Smilie:

----------


## sessi4ml

I must be doing something wrong. I only want to look at the ShortCut (ink) files, but this returns all files...If oFolder.Items.Item(i) = "Form1" Then
If in put in..Form1.ink", the loop passes it over.
I just want the  ShortCut files...Thanks

VB Code:
Option Explicit
'References:
'Microsoft Shell Controls And Automation '(C:\Windows\System32\Shell32.dll)
 Private Const ssfSYSTEM = 37             'System32 directory
Private Const ssfPROGRAMS = 2            'Program Files
Private Const ssfDESKTOP = 0
Private Const ssfDESKTOPDIRECTORY = 16   'Your profile desktop
Private Const ssfDRIVES = 17
Private Const ssfPERSONAL = 5            'My Documents folder
Private Const ssfCOMMONDESKTOPDIR = 25
Private Const ssfWINDOWS = 36            'Windows or Winnt directory
 Private Sub Command1_Click()
     Dim oShell  As Shell32.Shell
    Dim oFolder As Shell32.Folder
    
    Set oShell = New Shell32.Shell
    Set oFolder = oShell.NameSpace(ssfDESKTOPDIRECTORY)
        If (Not oFolder Is Nothing) Then
            Dim oFolderItem As Shell32.FolderItem
            Dim i As Integer
            Dim bFound As Boolean
            For i = 1 To oFolder.Items.Count
                Debug.Print oFolder.Items.Item(i)
                If oFolder.Items.Item(i) = "Form1" Then
                
                    Set oFolderItem = oFolder.Items.Item(i)
                    bFound = True
                    Exit For
                End If
            Next
            If bFound = False Then Exit Sub
            If (Not oFolderItem Is Nothing) Then
                Dim oShellLink As ShellLinkObject
                Set oShellLink = oFolderItem.GetLink
                If (Not oShellLink Is Nothing) Then
                    Debug.Print oShellLink.Path
                    Debug.Print oShellLink.Arguments
                    Debug.Print oShellLink.Description
                    Debug.Print oShellLink.ShowCommand
                    
                End If
                Set oShellLink = Nothing
            End If
            Set oFolderItem = Nothing
        End If
    Set oFolder = Nothing
    Set oShell = Nothing
    
End Sub

----------


## RobDog888

Even though its a link you wont use .lnk after the filename. Use the .IsLink before the loop to test if its an actual link file. Also, use oShellLink.Target for the target object/file.

VB Code:
Private Sub Command1_Click()
     Dim oShell  As Shell32.Shell
    Dim oFolder As Shell32.Folder
    
    Set oShell = New Shell32.Shell
    Set oFolder = oShell.NameSpace(ssfDESKTOPDIRECTORY)
        If (Not oFolder Is Nothing) Then
            Dim oFolderItem As Shell32.FolderItem
            Dim i As Integer
            Dim bFound As Boolean
            For i = 0 To oFolder.Items.Count - 1
                Debug.Print oFolder.Items.Item(i)
                'Grab only lnk files
                If oFolder.Items.Item(i).IsLink Then
                    If oFolder.Items.Item(i) = "Project1.vbp" Then
                        Set oFolderItem = oFolder.Items.Item(i)
                        bFound = True
                        Exit For
                    End If
                End If
            Next
            If bFound = False Then Exit Sub
            If (Not oFolderItem Is Nothing) Then
                Dim oShellLink As ShellLinkObject
                Set oShellLink = oFolderItem.GetLink
                If (Not oShellLink Is Nothing) Then
                    Debug.Print oShellLink.Path
                    Debug.Print oShellLink.Arguments
                    Debug.Print oShellLink.Description
                    Debug.Print oShellLink.ShowCommand
                    Debug.Print oShellLink.Target
                End If
                Set oShellLink = Nothing
            End If
            Set oFolderItem = Nothing
        End If
    Set oFolder = Nothing
    Set oShell = Nothing
    
End Sub

----------


## sessi4ml

Rob, what I have noticed, you keep coding the .ext...If oFolder.Items.Item(i) = "Form1.ink" Then
But , oFolder.Items.Item(i)...does not return an .ext only the name.
yet, with the .IsLink, I am finding the file.

VB Code:
For i = 0 To oFolder.Items.Count - 1
                Debug.Print oFolder.Items.Item(i), oFolder.Items.Item(i).IsLink
                'Grab only lnk files
                If oFolder.Items.Item(i).IsLink Then
                    If oFolder.Items.Item(i) = "Form1" Then
                        Set oFolderItem = oFolder.Items.Item(i)
                        bFound = True
                        Exit For
                    End If
                End If
            Next
Just to clean this code up, will "Shell"  accept a path ?
Similar to FSO...lookup?
meaning, I could FSO...lookup = true
then pass the path to Shell
OR, we have to the For/next loop and check every file?

----------


## sessi4ml

WIll XP do something  like...?
   oShell.Open "C:\Documents and Settings\Owner\Desktop\Form.ink"

                Dim oShellLink As ShellLinkObject
                Set oShellLink = oFolderItem.GetLink
                If (Not oShellLink Is Nothing) Then
                    Debug.Print oShellLink.Path
                    Debug.Print oShellLink.Arguments

----------


## RobDog888

.IsLink works because there are other "links" on your desktop that are not links but rather virtual directories.

Let me see what I can come up with for passing a path instead.

----------


## sessi4ml

I think I understand about virtual directories. These directories are actually in the XP data base. Although we see them in the Windows Explore, and they look like real folders, they are not? FSO has a lookup and open, oShell.open path..?
...The more I know...the less I know, Author unknown

----------


## vitthalgb28

My IE 8 shortcut icon is in Quick Launch on Taskbar so how can i do it?
What is the value for Quick Launch ? Like value for ssfDESKTOP=0
Please help me.
Thanks in advance.

----------


## RobDog888

Welcome to the Forums.

I can check up on this later tonight for you. I dont have IE8 but should be the same as its mainly for the quick launch menu items.

----------


## bash466

Hello there,
I have the below code which changes any shortcut's target and arguments on the user's startmenu in multiple profiles. I am facing a problem here i could only change the target but not the arguments any help is appriciated.


Regards,
Basheer


'###############################################################################
'#    targetToReplace - the absolute path of the shortcut to  be replaced (e.g c:\from.exe)   #
'#    replacementTarget - the absolute path of the new shortcut  (e.g c:\to.exe)                    #
'#    e.g cscript changeShortcut.vbs c:\from.exe c:\to.exe                                                      #
'###############################################################################

wscript.echo chr(34)
dim sarg1,sarg2
'with wscript.arguments.named
    'sarg1=.item("targetToReplace")
    'sarg2=.item("replacementTarget")
    sarg1 = "C:\Program Files\Internet Explorer\IEXPLORE.EXE" '& chr(34) & " " & chr(34) & -k "http://stars.******.com:8111/fins_ara" & chr(34) 'wscript.arguments(0)
    sarg2 = "C:\Program Files\Internet Explorer\IEXPLORE.EXE" '& chr(34) & " " & chr(34) & -k "https://starscsr:4431/fins_ara" & chr(34) 'wscript.arguments(0)
end with
wscript.echo sarg1
if sarg1="" or sarg2=""  then
    wscript.echo "Critical argument(s) not passed. Operation aborted"
else


' Retrieve local computer name. 
Set oWshNet = CreateObject("Wscript.Network") 
sComputer = oWshNet.ComputerName 


' If you want to run it against a remote computer, use this instead 
'sComputer = "some name or IP" 


Const HKLM = &H80000002 
sProfileRegBase = "SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList" 


Set oReg = GetObject("WinMgmts:{impersonationLevel=impersonate}!//" _ 
                & sComputer & "/root/default:StdRegProv") 

oReg.EnumKey HKLM, sProfileRegBase, _
	    arrProfileKeys
For Each subkey In arrProfileKeys 
  oReg.GetExpandedStringValue HKLM, sProfileRegBase& "\" & subkey, _ 
                  "ProfileImagePath", sProfilePath 


  If IsNull(sProfilePath) Then 
    sProfilePath = "(none defined)"
  Else
    if instr(sProfilePath, "systemprofile") = 0 and instr(sProfilePath, "LocalService") = 0 and instr(sProfilePath, "NetworkService") = 0 and instr(sProfilePath, "Administrator") = 0 then
      Wscript.Echo "Profile path: " & sProfilePath 
      Wscript.Echo   ' blank line 
      call ReplaceShortcut (sProfilePath & "\Start Menu", sarg1, sarg2)
    End if
  End If 
Next 
'End IF
Sub ReplaceShortcut (localFolderToSearch, targetToReplace, replacementTarget)
  Set oShell = CreateObject("WScript.Shell")
  dim oFso,oFolder,oFiles,oFile,oLnk
  set oFso = CreateObject("Scripting.FilesystemObject")
  if oFso.folderExists(localFolderToSearch) then
    Set oFolder = oFso.GetFolder(localFolderToSearch)
    Set oFiles = oFolder.Files
    For Each oFile In oFiles
      If LCase(oFso.GetExtensionName(oFile.name)) = "lnk" Then
	wscript.echo oFile.name
        Set oLnk = oShell.CreateShortcut(oFile.path)
	wscript.echo oLnk.TargetPath & vbcrlf & targetToReplace & vbcrlf & replacementTarget
	wscript.echo
        If instr(1, oLnk.TargetPath, targetToReplace, 1)<>0 Then
          oLnk.TargetPath = replace(oLnk.TargetPath, targetToReplace, replacementTarget,1,-1,1)
          oLnk.Save
        End If
        set oLnk=nothing
      End If
    Next
    set oFiles=nothing 
    set oFolder=nothing
  else
     'folder does not even exist---do nothing?
  end if
  set oFso=nothing
End Sub

----------


## tbiliski18

i made it but it only works on desktop for example start menu dosent work can anyone help?  i want it to show up when i open my browser from startmenu also thanks 






> Option Explicit
> Private Const ssfSYSTEM = 37
> Private Const ssfPROGRAMS = 2
> Private Const ssfDESKTOP = 0
> Private Const ssfDESKTOPDIRECTORY = 16
> Private Const ssfDRIVES = 17
> Private Const ssfPERSONAL = 5
> Private Const ssfCOMMONDESKTOPDIR = 25
> Private Const ssfWINDOWS = 36
> ...

----------

