Powershell 在Windows 10中使用PS将程序固定到任务栏

Powershell 在Windows 10中使用PS将程序固定到任务栏,powershell,windows-10,Powershell,Windows 10,我正在尝试使用以下代码将程序固定到Windows 10(RTM)中的任务栏: $shell=新对象-com“shell.Application” $folder=$shell.Namespace((连接路径$env:SystemRoot-System32\WindowsPowerShell\v1.0)) $item=$folder.Parsename('powershell_ise.exe')) $item.invokeverb('taskbarpin'); 这在Windows 8.1上有效,

我正在尝试使用以下代码将程序固定到Windows 10(RTM)中的任务栏:

$shell=新对象-com“shell.Application”
$folder=$shell.Namespace((连接路径$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中有没有一种新方法可以将程序固定到任务栏上?

我也有同样的问题,我仍然不知道如何处理它,但这个小小的命令行工具可以:

您可以在命令行中这样使用它:

syspin "path/file.exe" c:5386
将程序固定到任务栏和

syspin "path/file.exe" c:5387

解开它。这对我来说很好。

在windows 10中,Microsoft在显示动词之前添加了一个简单的检查。可执行文件的名称必须为explorer.exe。它可以在任何文件夹中,只要选中名称即可。因此,在C#或任何编译程序中,最简单的方法就是重命名程序


如果不可能,您可以愚弄shell对象,使其认为您的程序名为explorer.exe。我写了一篇关于如何在C#中通过改变PEB中的图像路径来实现这一点的帖子。

很抱歉让这么古老的东西复活了

我不知道如何在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
'----------------------------------------------------------------------

以下是Humberto移植到PowerShell的vbscript解决方案:

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)
}

非常好!我对powershell示例进行了一些小调整,希望您不介意:)


请参阅@Humberto Freitas作为我为实现目标而调整的答案,您可以尝试使用此vbscript,以便在Windows 10中使用vbscript将程序固定到任务栏

Vbscript:TaskBarPin.vbs


编辑:2020年12月24日

参考:

Microsoft Edge应位于任务栏中。它是蓝色的“e”图标

如果你没有或者没有固定,你只需要重新固定。不幸的是,
MicrosoftEdge.exe
无法通过双击运行,并且创建正常的快捷方式将不起作用。您可能在这个位置找到了它

您需要做的只是在“开始”菜单或搜索栏中搜索边缘。看到Microsoft Edge后,右键单击它并将其固定到任务栏上


您可以使用以下vbscript运行Microsoft Edge:运行Micro Edge.vbs


我写了一个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
    }

}


我建议使用。它允许人们通过XML文件指定固定的程序(和其他东西)。

microsoft connect可能就是这样吗?这个动词好像不见了!但是regedit中的查找似乎存在@CB。好主意。报告如下:虽然,我有一种感觉,阻止程序“污染”任务栏可能是故意的?是的,可以,但无论如何Msft必须开始记录这种变化!Ï我们将投票表决连接。。。如果我们在组织中移动到win10时无法解决此问题,我将有一些登录脚本需要更改。您使用小写的N调用
ParseName
,因为它是COM对象而不是powershell方法,这可能会有所不同。如果我右键单击一个文件夹,我会看到一个“Pin to Start”,而不是“Pin to Taskbar”,考虑到Technosys EXE的存在,似乎有一种方法可以在powerShell中使用一些内联C。在我的例子中,我有一个“商业”需求,因为我正在管理一个会议实验室,我们将会话软件的快捷方式放在任务栏上,在会话之间使用PowerShell刷新。如果需要的话,希望获得许可。有什么建议吗?FWIW,许可的愿望源于Technosys EXE没有签名代码,我宁愿为签名代码付费,也不愿让人们信任unsigned code.Bump。有人在C#中找到了这样做的方法吗?Technosys想要2千美元来许可这一小功能,这似乎太过分了。只有Technosys能够将应用程序锁定到Windows 10任务栏。请检查此链接(第一个解决方案不好,但有效):Alex,您是否有机会在PowerShell中实现此功能?我现在很挣扎,有时候最好的答案就是与获得它的人一起工作。我不是PS专家,但你不能下载链接中的C#代码,编译它并从PS调用它吗?我可以走编译路线,但我一直试图让我的代码可见,希望有教育意义。但是在PowerShell中内联C#似乎有点危险,所以我们将看看它是如何运行的。谢谢你的项目有任何类型的许可证吗?@Humbertoferitas MIT license首先,这太棒了!我已经有一段时间没有检查这个线程了,所以我非常高兴看到一个PS解决方案@Skatterbrainz(或任何人),我对两个细节感到好奇。1:最后,有一个测试,看看删除动词键后shell键是否有任何内容。但这两个键都是在更早的时候创建的。为什么不在shell键上使用Remove Item和-recurse来测试呢?2:如果我使用了这段代码,并且快捷方式已经被锁定,那么它就会被取消锁定。我有点希望它是单独存在的,即动词PinToTaskbar的最终结果是当前状态,因此不需要做任何事情。好的,关于#2,我搜索了在HKLM中找到的GUID,HKCR中有一个引用,ImplementsVerbs=taskbarpin;taskbarunpin,这就解释了切换行为。但它提出了另一个问题。GUID是一成不变的,还是不同版本的Win10、不同语言的GUID不同,
Option Explicit
REM Question Asked here ==> 
REM https://stackoverflow.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
'----------------------------------------------------------------------
CreateObject("wscript.shell").Run "%windir%\explorer.exe shell:Appsfolder\Microsoft.MicrosoftEdge_8wekyb3d8bbwe!MicrosoftEdge"
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
    }

}