Search code examples
c#.netvb.netwindowstaskbar

Alternative way to pin an exe to Windows Taskbar?


I'm looking for a way to pin an exe and/or a shortcut into the Windows 8.1 Taskbar (not in the StartMenu) without depending on the verb name.

I did a research and I only can find code-examples like this that does not works because they are verb-name language dependant, this means it checks for a verb titled "Pin To Taskbar" and then invoke it, but that verb does not exists with English name in other languages, for example in Spanish 'Pin To Taskbar' is translated as 'Anclar a la barra de tareas', I really hope that invoking a verb parsing its verb-name is not the unique way to perform this task.

Then I wonder whether the Microsoft's WindowsAPICodePack library maybe provides a way to perform this in a more efficient way, or at least in a way that really will works.

Or maybe using the Windows API SendMessage function?

Any ideas?


Solution

  • There is no official way to pin application to taskbar (at this time) as far as I know, so I think you will need to rely on that hacky way with verbs. But you don't need to (should not) hardcode them; they can be read from the shell32.dll library resource string table. Some time ago I wrote a script for Inno Setup which can pin app. to taskbar by using those verbs (based on this thread). One part of that code is reading necessary verbs from the shell32.dll library and that's what I've tried to translate to VB (that's my first time with VB.NET, so take the following code just as a proof of concept):

    Module Module1
    
        Const SHELL32_STRING_ID_PIN_TO_TASKBAR As Int32 = 5386
        Const SHELL32_STRING_ID_UNPIN_FROM_TASKBAR As Int32 = 5387
    
        Private Declare Auto Function LoadLibrary Lib "kernel32.dll" ( _
            ByVal lpLibFileName As String _
        ) As IntPtr
    
        Private Declare Function FreeLibrary Lib "kernel32.dll" ( _
            ByVal hLibModule As IntPtr _
        ) As Boolean
    
        Private Declare Auto Function LoadString Lib "user32.dll" ( _
            ByVal hInstance As IntPtr, _
            ByVal uID As Int32, _
            ByVal lpBuffer As String, _
            ByVal nBufferMax As Int32 _
        ) As Int32
    
        Public Function TryGetVerbName(ByVal ID As Int32, ByRef VerbName As String) As Boolean
            Dim Handle As IntPtr
            Dim BufLen As Int32
            Dim Buffer As String = Space(255)
    
            Handle = LoadLibrary("shell32.dll")
            If Not Handle.Equals(IntPtr.Zero) Then
                Try
                    BufLen = LoadString(Handle, ID, Buffer, Buffer.Length)
                    If BufLen <> 0 Then
                        VerbName = String.Copy(Buffer)
                        Return True
                    End If
                Finally
                    FreeLibrary(Handle)
                End Try
            End If
    
            Return False
        End Function
    
        Sub Main()
            Dim VerbName As String = String.Empty
    
            If TryGetVerbName(SHELL32_STRING_ID_PIN_TO_TASKBAR, VerbName) Then
                Console.WriteLine("Verb name for pin to taskbar: " + VerbName)
            End If
    
            If TryGetVerbName(SHELL32_STRING_ID_UNPIN_FROM_TASKBAR, VerbName) Then
                Console.WriteLine("Verb name for unpin from taskbar: " + VerbName)
            End If
    
            Console.ReadLine()
        End Sub
    
    End Module