Закрепить программу на панели задач с помощью PS в Windows 10

Я пытаюсь закрепить программу на панели задач в Windows 10 (RTM) с помощью этого кода:

$shell = new-object -com "Shell.Application"  
$folder = $shell.Namespace((Join-Path $env:SystemRoot System32\WindowsPowerShell\v1.0))
$item = $folder.Parsename('powershell_ise.exe')
$item.invokeverb('taskbarpin');

Это работало в Windows 8.1, но больше не работает в Windows 10.

Если я выполню $item.Verbs()Я получаю это:

Application Parent Name
----------- ------ ----
                   &Open
                   Run as &administrator
                   &Pin to Start

                   Restore previous &versions

                   Cu&t
                   &Copy
                   Create &shortcut
                   &Delete
                   Rena&me
                   P&roperties

Как видите, нет глагола для закрепления его на панели задач. Однако, если я щелкну правой кнопкой мыши по этому конкретному файлу, опция будет там:
Доступные глаголы в пользовательском интерфейсе

Вопросы:
Я что-то пропустил?
Есть ли в Windows 10 новый способ закрепления программы на панели задач?

9 ответов

Очень хорошо! Я сделал несколько небольших изменений в этом примере PowerShell, надеюсь, вы не против:)

param (
    [parameter(Mandatory=$True, HelpMessage="Target item to pin")]
    [ValidateNotNullOrEmpty()]
    [string] $Target
)
if (!(Test-Path $Target)) {
    Write-Warning "You freaking dumbass!!! $Target does not exist"
    break
}

$KeyPath1  = "HKCU:\SOFTWARE\Classes"
$KeyPath2  = "*"
$KeyPath3  = "shell"
$KeyPath4  = "{:}"
$ValueName = "ExplorerCommandHandler"
$ValueData =
    (Get-ItemProperty `
        ("HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\" + `
            "CommandStore\shell\Windows.taskbarpin")
    ).ExplorerCommandHandler

$Key2 = (Get-Item $KeyPath1).OpenSubKey($KeyPath2, $true)
$Key3 = $Key2.CreateSubKey($KeyPath3, $true)
$Key4 = $Key3.CreateSubKey($KeyPath4, $true)
$Key4.SetValue($ValueName, $ValueData)

$Shell = New-Object -ComObject "Shell.Application"
$Folder = $Shell.Namespace((Get-Item $Target).DirectoryName)
$Item = $Folder.ParseName((Get-Item $Target).Name)
$Item.InvokeVerb("{:}")

$Key3.DeleteSubKey($KeyPath4)
if ($Key3.SubKeyCount -eq 0 -and $Key3.ValueCount -eq 0) {
    $Key2.DeleteSubKey($KeyPath3)
}

Вот решение Vibercript от Humberto, портированное на PowerShell:

Param($Target)

$KeyPath1  = "HKCU:\SOFTWARE\Classes"
$KeyPath2  = "*"
$KeyPath3  = "shell"
$KeyPath4  = "{:}"
$ValueName = "ExplorerCommandHandler"
$ValueData =
    (Get-ItemProperty `
        ("HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\" + `
            "CommandStore\shell\Windows.taskbarpin")
    ).ExplorerCommandHandler

$Key2 = (Get-Item $KeyPath1).OpenSubKey($KeyPath2, $true)
$Key3 = $Key2.CreateSubKey($KeyPath3, $true)
$Key4 = $Key3.CreateSubKey($KeyPath4, $true)
$Key4.SetValue($ValueName, $ValueData)

$Shell = New-Object -ComObject "Shell.Application"
$Folder = $Shell.Namespace((Get-Item $Target).DirectoryName)
$Item = $Folder.ParseName((Get-Item $Target).Name)
$Item.InvokeVerb("{:}")

$Key3.DeleteSubKey($KeyPath4)
if ($Key3.SubKeyCount -eq 0 -and $Key3.ValueCount -eq 0) {
    $Key2.DeleteSubKey($KeyPath3)
}

У меня та же проблема, и я до сих пор не знаю, как ее решить, но этот маленький инструмент командной строки делает:

http://www.technosys.net/products/utils/pintotaskbar

Вы можете использовать его в командной строке следующим образом:

syspin "path/file.exe" c:5386

закрепить программу на панели задач и

syspin "path/file.exe" c:5387

открепить это. Это прекрасно работает для меня.

В windows 10 Microsoft добавила простую проверку перед показом глагола. Имя исполняемого файла должно быть explorer.exe. Это может быть в любой папке, только имя проверено. Таким образом, простой способ в C# или любой скомпилированной программе - просто переименовать вашу программу.

Если это невозможно, вы можете обмануть объект оболочки, думая, что ваша программа называется explorer.exe. Я написал здесь пост о том, как сделать это в C#, изменив путь к изображению в PEB.

Предупреждение. Ни один из ответов PowerShell/VBScript на этой странице не работает в Windows 10 21H2 или Windows 11 (и эта функция была нарушена еще в 2019 году).

Просто выделил это жирным шрифтом, чтобы люди не тратили здесь свое время. Надеюсь, кто-то сможет обновить приведенное выше (поскольку это были отличные ответы, но они больше не работают из-за того, что Microsoft вносит изменения, поэтому, надеюсь, некоторая настройка ответов здесь может заставить их снова работать). Поскольку в настоящее время не существует известного метода закрепления приложений на панели задач с помощью PowerShell (поскольку ни одно из решений на этой странице не работает), единственное известное мне решение — этоsyspin.exeприложение. Пожалуйста, можно обновить ответы PowerShell, так как это было бы намного лучше, чем использованиеsyspin. В настоящее время (и к сожалению) эта страница служит в основном «ловушкой для меда»; люди приходят сюда, счастливые найти ответ на этот вопрос, только для того, чтобы тратить свое время на поиски решений, которые все сломаны.

Извините, что воскресил что-то столь старое.

Я не знаю, как сделать это в PowerShell, но в VBScript вы можете сделать этот метод, который я разработал. Работает независимо от языка системы.

Работает на Windows 8.x и 10.

скрипт

If WScript.Arguments.Count < 1 Then WScript.Quit
'----------------------------------------------------------------------
Set objFSO = CreateObject("Scripting.FileSystemObject")
objFile    = WScript.Arguments.Item(0)
sKey1      = "HKCU\Software\Classes\*\shell\{:}\\"
sKey2      = Replace(sKey1, "\\", "\ExplorerCommandHandler")
'----------------------------------------------------------------------
With WScript.CreateObject("WScript.Shell")
    KeyValue = .RegRead("HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer" & _
        "\CommandStore\shell\Windows.taskbarpin\ExplorerCommandHandler")

    .RegWrite sKey2, KeyValue, "REG_SZ"

    With WScript.CreateObject("Shell.Application")
        With .Namespace(objFSO.GetParentFolderName(objFile))
            With .ParseName(objFSO.GetFileName(objFile))
                .InvokeVerb("{:}")
            End With
        End With
    End With

    .Run("Reg.exe delete """ & Replace(sKey1, "\\", "") & """ /F"), 0, True
End With
'----------------------------------------------------------------------

Командная строка:

pin and unpin: taskbarpin.vbs [fullpath]

Example: taskbarpin.vbs "C:\Windows\notepad.exe"

Обратитесь к ответу @Humberto Freitas, который я настроил для своей цели, вы можете попробовать этот vbscript, чтобы закрепить программу на панели задач с помощью Vbscript в Windows 10.

Vbscript: TaskBarPin.vbs

Option Explicit
REM Question Asked here ==> 
REM https://stackru.com/questions/31720595/pin-program-to-taskbar-using-ps-in-windows-10/34182076#34182076
Dim Title,objFSO,ws,objFile,sKey1,sKey2,KeyValue
Title = "Pin a program to taskbar using Vbscript in Windows 10"
'----------------------------------------------------------------------
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set Ws     = CreateObject("WScript.Shell")
objFile    = DeQuote(InputBox("Type the whole path of the program to be pinned or unpinned !",Title,_
"%ProgramFiles%\windows nt\accessories\wordpad.exe"))
REM Examples
REM "%ProgramFiles%\Mozilla Firefox\firefox.exe"
REM "%ProgramFiles%\Google\Chrome\Application\chrome.exe"
REM "%ProgramFiles%\windows nt\accessories\wordpad.exe"
REM "%Windir%\Notepad.exe"
ObjFile = ws.ExpandEnvironmentStrings(ObjFile)
If ObjFile = "" Then Wscript.Quit()
sKey1      = "HKCU\Software\Classes\*\shell\{:}\\"
sKey2      = Replace(sKey1, "\\", "\ExplorerCommandHandler")
'----------------------------------------------------------------------
With CreateObject("WScript.Shell")
    KeyValue = .RegRead("HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer" & _
    "\CommandStore\shell\Windows.taskbarpin\ExplorerCommandHandler")
    .RegWrite sKey2, KeyValue, "REG_SZ"
    
    With CreateObject("Shell.Application")
        With .Namespace(objFSO.GetParentFolderName(objFile))
            With .ParseName(objFSO.GetFileName(objFile))
                .InvokeVerb("{:}")
            End With
            
        End With
    End With
    .Run("Reg.exe delete """ & Replace(sKey1, "\\", "") & """ /F"), 0, True
End With
'----------------------------------------------------------------------
Function DeQuote(S)
    If Left(S,1) = """" And Right(S, 1) = """" Then 
        DeQuote = Trim(Mid(S, 2, Len(S) - 2))
    Else 
        DeQuote = Trim(S)
    End If
End Function
'----------------------------------------------------------------------

Я написал класс Powershell, используя приведенные выше ответы в качестве мотивации. Я просто поместил его в модуль, а затем импортировал в другие мои скрипты.

using module "C:\Users\dlambert\Desktop\Devin PC Setup\PinToTaskbar.psm1"

[PinToTaskBar_Verb] $pin = [PinToTaskBar_Verb]::new();

$pin.Pin("C:\Windows\explorer.exe") 
$pin.Pin("$env:windir\system32\SnippingTool.exe") 
$pin.Pin("C:\Windows\explorer.exe") 
$pin.Pin("C:\Program Files (x86)\Google\Chrome\Application\chrome.exe") 
$pin.Pin("C:\Program Files\Notepad++\notepad++.exe") 
$pin.Pin("$env:windir\system32\WindowsPowerShell\v1.0\PowerShell_ISE.exe") 

Модуль ниже

class PinToTaskBar_Verb 
{
    [string]$KeyPath1  = "HKCU:\SOFTWARE\Classes"
    [string]$KeyPath2  = "*"
    [string]$KeyPath3  = "shell"
    [string]$KeyPath4  = "{:}"
    
    [Microsoft.Win32.RegistryKey]$Key2 
    [Microsoft.Win32.RegistryKey]$Key3
    [Microsoft.Win32.RegistryKey]$Key4

    PinToTaskBar_Verb()
    {
        $this.Key2 = (Get-Item $this.KeyPath1).OpenSubKey($this.KeyPath2, $true)
    }
    

    [void] InvokePinVerb([string]$target)
    {
        Write-Host "Pinning $target to taskbar"
        $Shell = New-Object -ComObject "Shell.Application"
        $Folder = $Shell.Namespace((Get-Item $Target).DirectoryName)
        $Item = $Folder.ParseName((Get-Item $Target).Name)
        $Item.InvokeVerb("{:}")
    }



    [bool] CreatePinRegistryKeys()
    {
        $TASKBARPIN_PATH = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\CommandStore\shell\Windows.taskbarpin";
        $ValueName = "ExplorerCommandHandler"
        $ValueData = (Get-ItemProperty $TASKBARPIN_PATH).ExplorerCommandHandler
        
        Write-Host "Creating Registry Key: $($this.Key2.Name)\$($this.KeyPath3)"
        $this.Key3 = $this.Key2.CreateSubKey($this.KeyPath3, $true)

        Write-Host "Creating Registry Key: $($this.Key3.Name)\$($this.KeyPath4)"
        $this.Key4 = $this.Key3.CreateSubKey($this.KeyPath4, $true)

        Write-Host "Creating Registry Key: $($this.Key4.Name)\$($valueName)"
        $this.Key4.SetValue($ValueName, $ValueData)

        return $true
    }

    [bool] DeletePinRegistryKeys()
    {
        Write-Host "Deleting Registry Key: $($this.Key4.Name)"
        $this.Key3.DeleteSubKey($this.KeyPath4)
        if ($this.Key3.SubKeyCount -eq 0 -and $this.Key3.ValueCount -eq 0) 
        {
            Write-Host "Deleting Registry Key: $($this.Key3.Name)"
            $this.Key2.DeleteSubKey($this.KeyPath3)
        }
        return $true
    }

    [bool] Pin([string]$target)
    {
        try
        {
            $this.CreatePinRegistryKeys()
            $this.InvokePinVerb($target)
        }
        finally
        {
            $this.DeletePinRegistryKeys()
        }
        return $true
    }

}

Я рекомендую использовать эту функцию Windows 10. Это позволяет людям указывать закрепленные программы (и другие вещи) через файл XML.

Другие вопросы по тегам