Закрепить файл *.lnk на панели задач Windows 7 с помощью C#

Даже программное закрепление значков в Windows 7 кажется недопустимым (как здесь сказано: http://msdn.microsoft.com/en-us/library/dd378460(v=VS.85).aspx), есть несколько способов сделать это с помощью некоторого VB скрипты. Кто-то нашел способ сделать это на С# следующим образом:

private static void PinUnpinTaskBar(string filePath, bool pin)
{
     if (!File.Exists(filePath)) throw new FileNotFoundException(filePath);

     // create the shell application object
     dynamic shellApplication = Activator.CreateInstance(Type.GetTypeFromProgID("Shell.Application"));

     string path = Path.GetDirectoryName(filePath);
     string fileName = Path.GetFileName(filePath);

     dynamic directory = shellApplication.NameSpace(path);
     dynamic link = directory.ParseName(fileName);

     dynamic verbs = link.Verbs();
     for (int i = 0; i < verbs.Count(); i++)
        {
            dynamic verb = verbs.Item(i);
            string verbName = verb.Name.Replace(@"&", string.Empty).ToLower();

            if ((pin && verbName.Equals("pin to taskbar")) || (!pin && verbName.Equals("unpin from taskbar")))
            {

                verb.DoIt();
            }
        }

        shellApplication = null;
}

Как видно, код использует возможности .NET Framework 4.0. Вопрос, который я хочу задать: можно ли преобразовать эту функцию, чтобы она делала то же самое, но используя только 3.5 Framework? Любые идеи?


person movi    schedule 29.07.2011    source источник
comment
Я думаю, что этот вопрос следует перенести на codereview.stackexchange.com.   -  person Renatas M.    schedule 29.07.2011


Ответы (4)


Простой...

    private static void PinUnpinTaskBar(string filePath, bool pin) {
        if (!File.Exists(filePath)) throw new FileNotFoundException(filePath);

        // create the shell application object
        Shell shellApplication = new ShellClass();

        string path = Path.GetDirectoryName(filePath);
        string fileName = Path.GetFileName(filePath);

        Folder directory = shellApplication.NameSpace(path);
        FolderItem link = directory.ParseName(fileName);

        FolderItemVerbs verbs = link.Verbs();
        for (int i = 0; i < verbs.Count; i++) {
            FolderItemVerb verb = verbs.Item(i);
            string verbName = verb.Name.Replace(@"&", string.Empty).ToLower();

            if ((pin && verbName.Equals("pin to taskbar")) || (!pin && verbName.Equals("unpin from taskbar"))) {

                verb.DoIt();
            }
        }

        shellApplication = null;
    }

Не забудьте добавить ссылку COM в «Элементы управления и автоматизация Microsoft Shell».

Если вы хотите сохранить существующий метод использования Activator.CreateInstance, чтобы вам не нужно было иметь дополнительную DLL-библиотеку COM-взаимодействия, вам придется использовать отражение. Но это сделало бы код намного уродливее.

person James Johnston    schedule 29.07.2011
comment
Но это так по-хакерски. Там должен быть лучший способ! - person Mathias Lykkegaard Lorenzen; 20.10.2014
comment
@James, кажется, это изменилось для Windows 10. Имя глагола просто пустое, и невозможно вызвать метод «Сделать». Могла ли Microsoft заблокировать его? - person Tsury; 11.08.2015
comment
@Tsury Да, Microsoft заблокировала это. Но есть способы обойти это, см. мой ответ - person AlexDev; 10.08.2016

независимо от того, какую локализацию использовал пользователь Windows:

        int MAX_PATH = 255;
        var actionIndex = pin ? 5386 : 5387; // 5386 is the DLL index for"Pin to Tas&kbar", ref. http://www.win7dll.info/shell32_dll.html
        StringBuilder szPinToStartLocalized = new StringBuilder(MAX_PATH);
        IntPtr hShell32 = LoadLibrary("Shell32.dll");
        LoadString(hShell32, (uint)actionIndex, szPinToStartLocalized, MAX_PATH);
        string localizedVerb = szPinToStartLocalized.ToString();

        // create the shell application object
        dynamic shellApplication = Activator.CreateInstance(Type.GetTypeFromProgID("Shell.Application"));

        string path = Path.GetDirectoryName(filePath);
        string fileName = Path.GetFileName(filePath);

        dynamic directory = shellApplication.NameSpace(path);
        dynamic link = directory.ParseName(fileName);

        dynamic verbs = link.Verbs();
        for (int i = 0; i < verbs.Count(); i++)
        {
            dynamic verb = verbs.Item(i);

            if ((pin && verb.Name.Equals(localizedVerb)) || (!pin && verb.Name.Equals(localizedVerb)))
            {
                verb.DoIt();
                break;
            }
        }
person Sergio    schedule 19.11.2015

В Windows 10 вышеперечисленные методы не работают. Глагол «Закрепить на панели задач» не отображается в списке вашей программы, только в проводнике. Чтобы это работало в Windows 10, у вас есть два варианта. Либо переименуйте вашу программу в explorer.exe, либо вы должны обмануть объект, заставив его думать, что ваша программа называется explorer.exe. Вам нужно найти PEB и изменить поле пути к изображению. Я написал сообщение здесь о том, как это сделать. .

person AlexDev    schedule 10.08.2016

Обновление для приложений UWP, работающих в Windows 10 с обновлением Fall Creators (сборка 16299 или выше):

Вы можете программно закрепить собственное приложение на панели задач точно так же, как вы можете закрепить свое приложение в меню «Пуск». И вы можете проверить, закреплено ли ваше приложение в настоящее время и разрешает ли закрепление панель задач.

Вы можете напрямую обращаться к TaskbarManager API, как описано в документах MS.

Я хотел сделать это с помощью приложения WinForms, но не похоже, что это сработает, потому что я не могу ссылаться на Windows.Foundation API.

person Stanley G.    schedule 23.12.2019