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.

Finding what’s causing Windows 10 explorer constantly crashing

If you are here than you probably have the same problem that I had. The same problem that some of my colleagues had. You upgraded a Windows 7 or 8 installation to Windows 10, and now every few seconds Explorer freezes up for about a minute and then restarts.

Like I said, I have seen a few computers with this problem, and after a lot of searching was able to get them all working. Usually it was some incompatible component, and the solution (or workaround) was simply to rename it. But the thing is, each one was crashing because of a different component. Each time it was a different file I had to rename. Sometimes looking in Event Viewer can give the answer. You should give it a look before trying the procedure below. But sometimes Event Viewer yields nothing. It only reports a crash in Explorer.exe, which doesn’t help much. So how can we identify what component is causing the issue?

Process Monitor

Process monitor is a really useful tool which shows file system, registry and network activity for processes in real-time. In one of the cases, I used it to get a hint as to which component was causing the exception. If you don’t already have it you can download it from the link above. After downloading and running it, if not already in the filters screen, click on the funnel icon or choose Filter -> Filter (Ctrl-L), to open the filters dialog.

We want to see only activity from Explorer.exe. To do that, choose Process Name, is, type Explorer.exe, choose include and click Add.

Setting the filter to Include explorer.exe
Setting the filter to Include only Explorer.exe

Now you should see a lot of activity from Explorer.exe, all with the same PID. The next time it crashes though, you will also see activity from a new PID, until the first one ends up dying. You can already click on the magnifying glass to stop capturing more activity.

Second PID gets created
Second PID gets created

Now scroll up until before all the Thread Exit calls, if you see an event Create Process for C:\WINDOWS\system32\WerFault.exe you can ignore it, and before that there should be some activity related to the exception handling. That’s not the exception itself though, so you still haven’t found the problem.

Finding exception handling events
Finding exception handling events

Double click one of the events. In my case it was one of the registry queries. Click on stack, to confirm this is related to exception handling. You should see something like this:

Stack trace showing the activity is related to exception handling
Stack trace showing the activity is related to exception handling

If you see near the top of the stack (bottom of the screen) UnhandledExceptionFilter + some hex number great, you are almost done. If you see KERNELBASE.dll + some number instead, it means the symbols aren’t being loaded. It’s still possible to continue, but it will be harder. If you already see the symbols or if you want to proceed without them you can skip the following section.

Setting up symbols loading

If you want to see the symbols but they aren’t being loaded, you need to find a copy of dbghelp.dll and, according to this post, symsvr.dll. You might have them in you computer already, or you can download Debugging Tools from Microsoft. You can try looking in C:\Program Files (x86)\Microsoft Visual Studio {version}\Common7\IDE or C:\Program Files\Windows Defender, or install Debugging Tools from here, which will install the dlls to C:\Program Files\Windows Kits\10\Debuggers\x86 or C:\Program Files (x86)\Windows Kits\10\Debuggers\x64. Once you found these dlls go to Options->Configure Symbols then on DbgHelp.dll path enter the path of both dlls. They should be in the same folder. Symbol paths should already have srv*http://msdl.microsoft.com/download/symbols. Now when you go to the stack trace screen you should see Loading Symbols near the bottom and the function names should appear next to the Module.

Identifying the misbehaving file

The last events before the process terminates are related to the exception handling, and not to what actually caused the exception. You have to search up the events, looking at their stack, until you find one that’s not related to exception handling. In my case there were a lot of similar events all of which were still under UnhandledExceptionFilter (or KERNELBASE.dll + 0xF540F if you don’t have symbols) until I reached an event which wasn’t.

Blue still had UnhandledExceptionFilter in the beginning of the stack. Yellow was unrelated and red was where the problem lied.
Finding the culprit

All the events which still had UnhandledExceptionFilter in the stack trace are highlighted in blue. The first event before that is highlighted in yellow and in my case was unrelated to the problem. The one before that gave a hint where the exception might have occurred. Let’s see the stack:

Stack trace of event near the exception
Stack trace of event near the exception

Looking at the stack trace we can see that the system was probably loading ODBCCP32.CPL right before the exception occurred which is a strong indicator of where the problem was. To confirm my suspicion I renamed the file to ODBCCP32.CPL.BAK and finally the freezing stopped.

Using this procedure you can find the offending component, and you can look for specific solutions for it, such as updating it to it’s latest version. Or, you can just rename it “temporarily”, and your system will be usable.

Leave a comment if this helped you (or if it didn’t), and which was the component. It might save others some time!