Pinning a network program with a Jump List to the taskbar programmatically in windows 10 – Part 2

After learning how to pin to the Taskbar programmatically in part 1, the next step is to pin a program on the network. One easy solution commonly given is to pin another program such as calculator, or a local copy of the network program, and change the created shortcut to point to the program on the network. But this involves typing and clicking and is error-prone, which means inevitably some users will be unable to do it. We are software developers. We are supposed to be creating solutions to users’ problems, and we don’t want to bother them with these annoyances. So unless you plan on doing this manually for each one of your users, read on..

Pinning programs with a Jump List

There is another major drawback to the methods linked above. If your application uses a Jump list, it will not be displayed on the pinned button, it will appear on a new button and be gone when the program is closed, rendering the Jump list practically useless. What you get is something similar to this, and the underlying cause in some cases is actually the same.

The reason for this is that when you pin a program through explorer, the shortcut includes the AppID used in the Jump list. When you pin it using the method above, the shortcut doesn’t include the AppID, and the Jump list isn’t associated with it.

Putting it all together

So what we have to do, like in the solutions above, is to pin a local program such as notepad.exe, and change the properties of the shortcut that is created, including the appID, to the correct values, all programmatically. After that we notify the shell to update itself, so we can see the new icon.

I changed the program from the last post based on this article from emoacht, which is modified from another article based on another one which is ultimately a wrapper around the IShellLink interface.

You can download the source here, or a compiled version here.

The new program:

Here is the ShellLink wrapper which I took from emoacht and just added a few properties:

 

Pinning a network program with a Jump List to the taskbar programmatically in windows 10 – Part 1

Update: You can download a working sample here.

That’s a long title. That’s because if you take any part away from it it becomes an easy task. For example, pinning programmatically on Windows 7 has a solution here. But that method doesn’t work on Windows 10. Yet. This is the relevant code:

Also, pinning a local program is much easier than pinning one on the network, which isn’t officially allowed. The usual workaround is pinning another program to the taskbar and then changing the shortcut created in C:\Users\Alexandre\AppData\Roaming\Microsoft\Internet Explorer\Quick Launch\User Pinned\TaskBar. But if your program uses a Jump List, it will not be displayed on the pinned button, it will appear in a new button, and will be gone when you close the app, which is pretty lame. You can solve that by copying the network program locally, pinning it, and then changing the path to the network. Not very practical though, and definitely not programmatic.

So how can it be done you are asking? In this post I’ll outline how to pin on windows 10 and in part 2 I will show how to pin a program on the network with a working Jump List. I will be posting the code for this soon.

Pinning to the Taskbar programmatically on Windows 10

The solution to pin to the taskbar in windows 7 involved listing the verbs on the shell COM object, and invoking the one with the title ‘Pin to Taskbar’. But in windows 10, all the verbs that appear when right clicking the file in explorer show up in the COM object, except for the ‘Pin to Taskbar’ verb. It’s obviously the same object that’s providing the list, but for some reason one of the items only appears in explorer. My first attempt was renaming my program to explorer.exe. I thought maybe it’s just a simple check. Turns out, it is just a simple check. The program doesn’t even have to be in %windir%. Renaming your app to explorer.exe causes the missing verb to appear, and allows any program to be pinned programatically. You could even write a separate program called explorer.exe and leave it alongside your main app and call it to do the pinning. But who wants to rename their program? And who wants to leave more executables lying around with their app? Besides, what’s the fun in that?

So after some poking around, I discovered where the name of the app is stored in the process memory, and by changing that value before the first time you invoke the shell object, you can fool it into thinking your app is explorer.exe. And you can do that in C# using Marshall.Write, in the safety of safe code. You can skip right to the end of the post for the code, or you can read the explanation below.

Finding the PEB in C#

The first step is finding the location of the PEB. The PEB is the structure that contains all the information about the process that is running, including environment variables, modules loaded and, yes, the name of the image that is running. There is an undocumented function in ntdll.dll called NtQueryInformationProcess which will give us the base address of the PEB. This function might be changed in the future, but for windows 10 we should be safe. After that we navigate the structure using different offsets for 32 and 64-bit processes to find the Image Path. (I only tested this on 64-bit so if it doesn’t work on 32 bit the offsets might be wrong) and use the Marshall functions to change the value. After that we can use the old method of invoking the verbs.

I will write another post soon showing how to pin a program on the network, so be sure check for updates!

Using the code

This is how you use the code:

And this is the supporting code. Thanks to the Process Hacker v1 project for the code to find the base address of the PEB. I removed a few enums for brevity. Drop it in a static class for the Increment function to work.