Как предотвратить закрепление приложения в Windows 7?

Я пытаюсь запретить пользователю закреплять мое приложение .NET на панели задач. Я нашел код на Старая новая вещь, который просто это. Тем не менее, это на С++.

#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;
}

Мне очень не повезло преобразовать его в С#. Кто-нибудь может помочь?


person AngryHacker    schedule 16.06.2011    source источник
comment
У вас есть код С# для этого? Я просто ссылаюсь на пакет кода Windows API, поэтому я думаю, что мне нужен только код, который является вашей основной формой? Заранее спасибо.   -  person Scott Wylie    schedule 14.03.2013


Ответы (3)


Вы можете загрузить Windows API Code Pack с необходимыми вызовами p/invoke. вам нужно перевести код в вашем посте на С#.

Либо используйте библиотеку целиком, либо найдите конкретные вызовы и определения, которые вам нужны (найдите в ней SHGetPropertyStoreForWindow, а затем другие ее зависимости).

person Andrei    schedule 16.06.2011
comment
Этот стакан наполовину полон, TaskbarNativeMethods — это внутренний класс. - person Hans Passant; 17.06.2011
comment
@Hans Passant: Это комментарий, связанный с проблемой лицензирования? Он мог бы использовать их реализацию как подсказку для своей собственной. В любом случае, внутренний класс доступен через WindowProperties, который является общедоступным. - person Andrei; 17.06.2011
comment
Ничего общего с лицензией. Да, ему придется скопировать и вставить объявления из исходного кода пакета кода. - person Hans Passant; 17.06.2011
comment
@Hans, @Andrei Я скопировал и вставил метрическую тонну кода, необходимого только для этой одной функции. Получилось около 50 тыс. кода С#. - person AngryHacker; 18.06.2011
comment
@AngryHacker: Может быть, проще использовать все как есть. Вы можете найти для него другое применение в будущем, и это сэкономит вам еще один сеанс копирования-вставки. - person Andrei; 18.06.2011

В этом вопросе в сообщении Old New Thing также говорится о том, как вы можете установить некоторые параметры реестра для каждого приложения, чтобы предотвратить закрепление приложения на панели задач.

Все, что вам нужно сделать, это добавить значение «NoStartPage» к ключу вашего приложения в папке Root\Applications. Значение может быть пустым и любого типа, если Windows просто увидит, что оно есть, оно не покажет возможность закрепить приложение, когда пользователь щелкнет его правой кнопкой мыши на панели задач.

Вот документация Microsoft по этой функции: Используйте реестр, чтобы приложение

Одно предостережение заключается в том, что в Windows 7 из-за UAC вам нужно запускать от имени администратора для обновления реестра. Я сделал это через app.manifest.

Ниже приведен код для поиска и обновления правильных разделов реестра (надеюсь, он не слишком подробный):

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);                    
            }
        }
    }
person Scott Wylie    schedule 03.05.2013

Используя WindowsAPICodePack (через NuGet), вам нужен код, похожий на:

// 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");
person Drew Noakes    schedule 29.04.2016