How to prevent an app from being pinned in Windows 7?
Asked Answered
H

3

6

I am trying to prevent the user from pinning my .NET app to the taskbar. I've found some code on the Old New Thing that does just that. However, it is in C++.

#include <shellapi.h>
#include <propsys.h>
#include <propkey.h>

HRESULT MarkWindowAsUnpinnable(HWND hwnd)
{
 IPropertyStore *pps;
 HRESULT hr = SHGetPropertyStoreForWindow(hwnd, IID_PPV_ARGS(&pps));
 if (SUCCEEDED(hr)) {
  PROPVARIANT var;
  var.vt = VT_BOOL;
  var.boolVal = VARIANT_TRUE;
  hr = pps->SetValue(PKEY_AppUserModel_PreventPinning, var);
  pps->Release();
 }
 return hr;
}


BOOL
OnCreate(HWND hwnd, LPCREATESTRUCT lpcs)
{
 MarkWindowAsUnpinnable(hwnd);
 return TRUE;
}

I am having very little luck converting it to c#. Can someone help?

Hector answered 16/6, 2011 at 20:20 Comment(1)
Do you have the C# code for this? I am just referencing the Windows API Code Pack so I think I only need the code that is your main form? Thanks in advance.Gensmer
C
9

You can download the Windows API Code Pack which has the necessary p/invoke calls you need to translate the code in your post to C#.

Either use the library in whole or find the specific calls and definitions you require (search it for SHGetPropertyStoreForWindow and then its other dependencies).

Chichihaerh answered 16/6, 2011 at 20:48 Comment(5)
That glass is only half-full, TaskbarNativeMethods is an internal class.Debbi
@Hans Passant: Is this a licensing issue related comment? He could use their implementation as hint for his own. Anyway, the internal class is exposed via WindowProperties which is public.Chichihaerh
Nothing to do with licensing. Yes, he'll have to copy-paste declarations from the code pack source code.Debbi
@Hans, @Chichihaerh I did copy & paste a metric ton of code required just for this one function. Turned out to be about 50k of c# code.Hector
@AngryHacker: Might be easier to just use all of it as-is. You may find other uses for it in the future and it will save you another copy-paste session.Chichihaerh
G
0

In the question, the Old New Thing post also talks about how you can set some registry settings on per application basis that will so prevent the pinning an application to the taskbar.

All you have to do is add the value of "NoStartPage" to a key for your application under the Root\Applications. The value can be blank and of any type, if Windows just sees it is there it will not show the ability to pin the app, when the user right clicks on it in the taskbar.

Here is the documentation from Microsoft on this feature: Use Registry to prevent pinning of an application

The one caveat to this is that in Windows 7, due to UAC, you have to run as administrator to update the registry. I did this via the app.manifest.

The code to find the right and update the correct registry keys is below (hopefully it is not too verbose):

public static void Main(string[] args)
    {
        // Get Root
        var root = Registry.ClassesRoot;

        // Get the Applications key
        var applicationsSubKey = root.OpenSubKey("Applications", true);

        if (applicationsSubKey != null)
        {
            bool updateNoStartPageKey = false;

            // Check to see if your application already has a key created in the Applications key
            var appNameSubKey = applicationsSubKey.OpenSubKey("MyAppName.exe", true);

            if (appNameSubKey != null)
            {
                // Check to see if the NoStartPage value has already been created
                if (!appNameSubKey.GetValueNames().Contains("NoStartPage"))
                {
                    updateNoStartPageKey = true;
                }
            }
            else
            {
                // create key for your application in the Applications key under Root
                appNameSubKey = applicationsSubKey.CreateSubKey("MyAppName.exe", RegistryKeyPermissionCheck.Default);

                if (appNameSubKey != null)
                {
                    updateNoStartPageKey = true;
                }
            }

            if (updateNoStartPageKey)
            {
                // Create/update the value for NoStartPage so Windows will prevent the app from being pinned.
                appNameSubKey.SetValue("NoStartPage", string.Empty, RegistryValueKind.String);                    
            }
        }
    }
Gensmer answered 3/5, 2013 at 4:30 Comment(0)
S
0

Using the WindowsAPICodePack (via NuGet) you need code resembling:

// Ensure the handle is available
new WindowInteropHelper(window).EnsureHandle();

// Prevent the window from being pinned to the task bars
var preventPinningProperty = new PropertyKey(
        new Guid("9F4C2855-9F79-4B39-A8D0-E1D42DE1D5F3"), 9);
WindowProperties.SetWindowProperty(window, preventPinningProperty, "1");
Sinistrad answered 29/4, 2016 at 15:36 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.