Powershell Windows 高速化、クィックアクセスの代わりに最近使ったファイルをピン止めする

# これ自体を復活させてもよい
別にクィックアクセスと同居してもよい

# 身もふたもないが
このスクリプトは力業かつ安定しないので、Shell:Recentで開き、ALT↑で一段上に上がり、右クリックでピン止めにするという通常の方法が早いかもしれない。

## Windows 11だとこんな感じ
最近使った項目というタイトルになる。
ファイルとフォルダのショートカットが含まれている。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/126919/ae7e025d-5248-dd27-3aa8-30d6c05bbc90.png)

## Windows11はこんな感じで設定
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/126919/a6b1a78b-367c-d65f-d03f-d1396a7fc98d.png)

Widnows11でクィックアクセスを表示させるには、なんでかフォルダーオプションのプライバシーで設定する。


# 日本語版でのみ可能
これは右クリックメニューを呼び出しているらしい。
[PowerShell でスタートメニューにプログラムをピン止めする](http://www.vwnet.jp/Windows/w10/2017052701/Pin2Start.htm)
Win+Rで Shell:recent
で取得できるが、やればわかるが、ユーザー名が入る。
というわけで、汎用性を保つには、環境変数を使わないと取得できない。

## Windows 10

```powershell
$Shell = new-object -com "Shell.Application"
$recentPath =  (Join-Path $env:APPDATA  '\Microsoft\Windows\Recent')
$Namespace = $Shell.Namespace($recentPath )
$Target = $Namespace.Self
if($PSUICulture -eq 'ja-jp'){
$Verb = $Target.Verbs() | ? {$_.Name -match "^クイック.+アクセスに.+ピン留め.+"}
}
$Verb.DoIt()
```
Window10 だとこんな表現でよいのだが、Windows11はうまくいかない。やはり、力業ということか。

## Windows 11

```powershell
# 最近使った項目をホームにピン止め
$Shell = new-object -com "Shell.Application"
$recentPath =  (Join-Path $env:APPDATA  '\Microsoft\Windows\Recent')
$Namespace = $Shell.Namespace($recentPath )
$Target = $Namespace.Self
$Verb = $Target.Verbs() | ? {$_.Name -like "クイック アクセスにピン留めする(&Q)"}
$Verb.DoIt()
```

## Windows10のサンプル

PowerShell でスタートメニューにプログラムをピン止めする
http://www.vwnet.jp/Windows/w10/2017052701/Pin2Start.htm
PowerShell でクイックアクセスにフォルダーをピン止めする
https://www.vwnet.jp/windows/w10/2017020201/Pin2QuickAccess.htm

## ゴミ箱との比較
[特殊フォルダやプログラムのCLSID一覧とShellコマンド一覧 | 初心者備忘録](https://www.ka-net.org/blog/?p=8432)
ちょっと話がそれるが、海外のサンプルでゴミ箱をクィックアクセスに加えるというのがあり、この内容が本記事と違う手法をとり、その不安定性について解説しているので、これを紹介する。

## 余談：ClassIDでフォルダを開く方法
ClassIDで開くためにはWin+Rで
`Shell:::'
に続けると開くことができる。
このため、ごみ箱はこのように開くことができる。
またexplorerのアドレス欄に入れても作動する。
`Shell:RecycleBinFolder`
`Shell:::{645FF040-5081-101B-9F08-00AA002F954E}`

## RecentはShellで開けるClassIDが存在しない？
しかしレジストリを検索しても、
`HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\FolderDescriptions\{AE50C081-EBD2-438A-8655-8A092E34987A}`
ここがRecentらしいのだが、動かない。このGUIDではないので、`Shell:Recent`しかないらしい。

## 以下のコードは安定しないらしい
これはヒントがあって、もう一つの方法として、PintoHomeがある。
実はクィックアクセスに登録するのではなく、クィックアクセスはHomeにある（上の写真でもそうなっている）のでこうした命令になるようだ。
しかしながら、本記事の方法と同様、標準的に供給された機能ではないため、安定しない。
なので、以下の記事とコードはPintoHomeの例と、その効果の問題点を引用しているものであり、レジストリを直接扱っているのと今回のRecentはどうもうまくいっていないので、試行しないことを推奨する。

### ちょっと解説
#### HKCU:\Software\Classes\CLSID\{645FF040-5081-101B-9F08-00AA002F954E}\
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/126919/8d96f796-1dea-b788-4ebd-a83e67d19968.png)

#### Command DelegateExecute について
Shellコマンド一覧
Shellコマンドで指定できるコマンド名は、レジストリの「HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\FolderDescriptions」以下から、Nameエントリを適当に抜き出してみました。
[Windows レジストリ 解剖記: HKEY_CLASSES_ROOT - Programming Field](https://www.pg-fl.jp/program/winreg/classes.htm)
いくつかの例から、本来exeで実行するはずの命令をComで実行するときにこの代理実行という命令を用いるようだ。
[Win 7編: デスクトップのコンテキストメニューをランチャー化する(後編) ](https://news.mynavi.jp/article/windows-101/)
[最近使ったファイルの履歴が残されていた。（recentフォルダーに残る） ](https://answers.microsoft.com/ja-jp/windows/forum/all/%E6%9C%80%E8%BF%91%E4%BD%BF%E3%81%A3%E3%81%9F/4a3ab053-2052-4a85-ba61-ed103cdd3008)
[ファイル管理システムのエクスプローラーが開かなくなりました](https://oshiete.goo.ne.jp/qa/9057873.html)
このあたりのサンプルを見ても、かなりヤバい機能でしかないことがわかる。
クィックアクセスや最近使った項目、タスクバー、スタートメニューってそんなヤバいのか!?

## 力業？ その２ごみばこ
https://superuser.com/questions/1742854/powershell-add-the-recycle-bin-to-quick-access

[windows explorer - PowerShell, add the Recycle Bin to Quick access - Super User](https://superuser.com/questions/1742854/powershell-add-the-recycle-bin-to-quick-access)

繰り返すが、、これはレジストリをいじるので非推奨、なのでコメント化している。

```powershell
<#
$RBPath = 'HKCU:\Software\Classes\CLSID\{645FF040-5081-101B-9F08-00AA002F954E}\shell\pintohome\command\'
$name = "DelegateExecute"
$value = "{b455f46e-e4af-4035-b0a4-cf18d2f6f28e}"
New-Item -Path $RBPath -Force | out-null
New-ItemProperty -Path $RBPath -Name $name -Value $value -PropertyType String -Force | out-null
$oShell = New-Object -ComObject Shell.Application
$trash = $oShell.Namespace("shell:::{645FF040-5081-101B-9F08-00AA002F954E}")
$trash.Self.InvokeVerb("PinToHome")
Remove-Item -Path "HKCU:\Software\Classes\CLSID\{645FF040-5081-101B-9F08-00AA002F954E}" -Recurse
#>
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/126919/38172036-4653-0d3f-50ac-fcb34520b6d4.png)
Name:DelegateExecute

> Value:`HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID\{645FF040-5081-101B-9F08-00AA002F954E}\shell\empty\command`
>これは実際には PS コードの問題でも、プログラムの問題でもありません。  これは OS 固有の制限/障害です。
 Windows エクスプローラーはプログラムであるため、Windows エクスプローラーが直接提供する機能があり、外部では利用できる場合とできない場合があります。
 Microsoft がこれを行うためのハンドルを提供していない場合、それを発見するには Windows エクスプローラーに関連する多くのハッキングが必要になります。
 私個人としては、この固定作業の使用例がわかりません。すでにデスクトップの [スタート] メニューから利用可能であり、タスクバーに固定して素早くアクセスすることもできるからです。しかし、X または Y の物事やアプローチにはそれぞれ理由があります。
 Windows エクスプローラーの機能を詳しく調べるとき。  たとえば、ここに記載されているように: Shell.Explore,Method;  このことから、Windows エクスプローラーでは、パス入力でこのようなことを行うだけでフォルダー時間に到達できることがわかります。  シェル:送信先。
 それでも、Recycle、shell:desktop\Recycle Bin に対してそれを試みると、すでに述べた理由で失敗します。  したがって、他の可能性については、そのようなドキュメントをさらに詳しく調べる必要があります。  RB は、アプリ呼び出しへの単なる .lnk です。
Windows エクスプローラーのすべての特殊フォルダーには、次のようなフォルダーがあります。
Desktop
Programs
MyDocuments
Personal
Favorites
Startup
Recent
SendTo
StartMenu
MyMusic
MyVideos
DesktopDirectory
MyComputer
NetworkShortcuts
Fonts
Templates
CommonStartMenu
CommonPrograms
CommonStartup
CommonDesktopDirectory
ApplicationData
PrinterShortcuts
LocalApplicationData
InternetCache
Cookies
History
CommonApplicationData
Windows
System
ProgramFiles
MyPictures
UserProfile
SystemX86
ProgramFilesX86
CommonProgramFiles
CommonProgramFilesX86
CommonTemplates
CommonDocuments
CommonAdminTools
AdminTools
CommonMusic
CommonPictures
CommonVideos
Resources
LocalizedResources
CommonOemLinks
CDBurning
また、クイック アクセスなどはその中には含まれないことに注意してください。したがって、shell: は、そのリストの他のいくつかのオプションと同様に、そのオプションではありません
アップデート

>つまり、私のコメントによると...あなたが作成したものは何でも操作できます。 ...GUID にはコメントを使用してください。次に、次のようにするだけです。

>これにより、そのプロパティを確認するまで、その新しいディレクトリが GUID なしの名前のみでクイック アクセス リストに追加されます。しかし、手動で作成したフォルダーをクリーンアップまたは削除しようとするとどうなるでしょうか? Windows エクスプローラーを閉じて再起動すると、QA のピンと一緒に消えてしまいます。



```powershell
<#
New-Item -Path 'C:\' -Name Temp -ItemType Directory -Force
New-Item -Path 'C:\temp' -Name 'Recycle Bin.{645FF040-5081-101B-9F08-00AA002F954E}' -ItemType Directory
($TargetShellObject = (Get-ChildItem -Path 'C:\Temp' -Filter 'Recycle*').FullName)
$oShell = New-Object -ComObject Shell.Application
$oShell.Namespace("$TargetShellObject").Self.InvokeVerb("PinToHome")
#>
```



> つまり、一度そのフォルダー オブジェクトを作成すると、削除することはできません。したがって、他の人が削除できないようにするには、非表示にするか保護する必要があります。したがって、このようなもの...

> ### アップデート

> コメントの通りです。 $env:windir を使用すると、同じ結果が得られます。ビュー設定に関係なく GUID がまったく表示されないため、パスのみが表示されるタイルを保存します。

>図略
デモのように、これはすべて Windows サンドボックスの初期環境で行われます。

# 参考
## GuID GodMode
[「GodMode」以外にもあった「Windows 7」の隠し機能--マイクロソフト幹部が自ら公開](https://xtech.nikkei.com/it/article/MAG/20100107/342962/)
## TaskBar
[PowerShell Commands for PinnedItem Item to Taskbar (This PC, User's Profile & Disk D:)](https://learn.microsoft.com/en-us/answers/questions/1309489/powershell-commands-for-pinneditem-item-to-taskbar)
## Shellオブジェクト
[スクリプト可能なシェル オブジェクト](https://learn.microsoft.com/ja-jp/windows/win32/shell/scriptable-shell-objects-roadmap)
上記の記事で機能として提供され知ているというのはスクリプト可能ということではないか。

## Starメニューに表示させるほうの削除する
最近使った項目はスタートメニューをクリックしたときに表示する場合の設定。
### Windows 10
[NEC LAVIE公式サイト > サービス＆サポート > Q&A > Q&A番号 021224 Windows 10でスタートメニューの「最近使ったアイテム」を非表示にする方法](https://faq.nec-lavie.jp/qasearch/1007/app/servlet/relatedqa?QID=021224)
### Windows 11
[NEC LAVIE公式サイト > サービス＆サポート > Q&A > Q&A番号 023814 Windows 11でスタートメニューの「最近使ったアイテム」を非表示にする方法]
## 英語の説明

[Pin, remove, and customize in Quick access - Microsoft Support](https://support.microsoft.com/en-us/windows/pin-remove-and-customize-in-quick-access-7344ff13-bdf4-9f40-7f76-0b1092d2495b)

[PowerShell Commands for PinnedItem Item to Taskbar (This PC, User's Profile & Disk D:)](https://learn.microsoft.com/en-us/answers/questions/1309489/powershell-commands-for-pinneditem-item-to-taskbar)