集成到右鍵菜單
如有錯誤,歡迎指出
在資源管理器中,空白處右鍵(right-clicking on folder backround in Windows Explorer)會彈出菜單,其中有如“在此處打開cmd”等選項,這些選項顯著提高了“工作”效率。這篇文章所要講述的即為:“如何將MSYS2
集成到右鍵菜單中——編輯注冊表”。
背景知識
注冊表
資源管理器“右鍵菜單”的注冊表項位於HKCR\Directory\
中。其中,Background\shell\
決定了在空白處右擊(right-clicking on folder backround in Windows Explorer),彈出的菜單內容;shell\
決定了在文件夾上(on folder itself)右擊,彈出菜單的內容。

這里根據子項cmd
,做一個簡單的解釋:
cmd
cmd\command
Extended
,空值,擁有該數據項意味着當按住shift
鍵右擊時,才可看到該菜單項,否則按住shift
與否,均可看到;
HideBasedOnVelocityId
,查看Powershell
可發現其擁有ShowBasedOnVelocityId
,這兩個數據項決定了,誰隱藏,誰顯示;
MUIVerb
:菜單項的顯示文本。如果沒有該數據項,則顯示(默認)
數據項的值(雖然在cmd
中,看起來很奇怪),如果(默認)
未設置值或為空值,則顯示為項名稱;
command
子項,(默認)
數據項:即為要執行的命令,其中%V
表示當前目錄,是注冊表內置的變量;
若傳遞了錯誤的注冊表變量,甚至會導致 explorer.exe 進程重啟。
Icon
:.ico
圖標文件的路徑;
SubCommands
:二級菜單項列表,用;
分隔,對應實體位於HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\CommandStore\shell\
中。
有趣的是,當
(默認)
被設置為空值或其它值后,可以看到標志着存在二級菜單的>
,但卻無法彈出二級菜單;另外,如果列表中對應的項不存在,也同樣無法彈出二級菜單。![]()
啟動方式
在開始菜單中,有MSYS2 64bit
,其中有三個快捷方式分別用於啟動MSYS2
的三個子系統。
C:\Users\xxxx\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\MSYS2 64bit
查看屬性可知,它們都調用了一個叫做msys2_shell.cmd
的腳本,該腳本位於MSYS2
安裝目錄下,傳遞/?
查看以可用選項。
結合 bat常用命令 以幫助閱讀該腳本。
注冊表文件
注冊
Windows Registry Editor Version 5.00
[HKEY_CLASSES_ROOT\Directory\Background\shell\MSYS2]
"MUIVerb"="Open MSYS2 Here"
"Extended"=""
"SubCommands"="MSYS2.MSYS;MSYS2.MinGW 64-bit"
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\CommandStore\shell\MSYS2.MSYS]
"MUIVerb"="MSYS"
"Icon"="D:\\msys64\\msys2.ico"
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\CommandStore\shell\MSYS2.MSYS\command]
@="D:\\msys64\\msys2_shell.cmd -msys -here"
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\CommandStore\shell\MSYS2.MinGW 64-bit]
"MUIVerb"="MinGW 64-bit"
"Icon"="D:\\msys64\\mingw64.ico"
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\CommandStore\shell\MSYS2.MinGW 64-bit\command]
@="D:\\msys64\\msys2_shell.cmd -mingw64 -here"
刪除
Windows Registry Editor Version 5.00
[-HKEY_CLASSES_ROOT\Directory\Background\shell\MSYS2]
[-HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\CommandStore\shell\MSYS2.MSYS]
[-HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\CommandStore\shell\MSYS2.MinGW 64-bit]
其它啟動方案
上面通過使用msys2_shell.cmd
啟動,可以很明顯地看到閃現出一個cmd
黑框,這是運行批腳本無法避免的問題。
但通過開始菜單中的快捷方式啟動時,幾乎看不到黑框。
在Lauchers中,還有一些其它方案:
- https://gist.github.com/magthe/a60293fe395af7245a9e
- 右鍵菜單集成,通過調用
mintty.exe
啟動。
- 右鍵菜單集成,通過調用
- https://github.com/msys2/msys2-launcher
- 該項目提供了
msys2.exe
、mingw64.exe
、mingw32.exe
,它們分別讀取同名的.ini
文件,以啟動對應的子系統。
- 該項目提供了
- https://gist.github.com/elieux/ef044468d067d68040c7
- 右鍵菜單集成,通過調用
msys2-launcher
中的.exe
啟動。(無黑框)
- 右鍵菜單集成,通過調用
事實上,上面的幾個方案最終都調用了mintty.exe
。
最終方案
上面已經說明了如何通過修改注冊表添加右鍵菜單,並給出了msys2
的一種啟動方式,但該方法並不完美。
The idea
在Lauchers的最后,The idea部分,說到:
如果你需要正確啟動一個shell,但上面提及的方法中又沒有適合的,那么可以基於下面的知識來制定你自己的方法:
- 在環境中設置
MSYSTEM=...
,其值可為MSYS
,MINGW32
,或MINGW64
; - 而后運行一個 login shell。
如果條件限制你只能使用一行語句,那么典型的寫法是:
C:/msys64/usr/bin/env MSYSTEM=MSYS /usr/bin/bash -li
另外,如果需要保持當前工作目錄,那么還需要設置CHERE_INVOKING=1
;如果你需要運行一個特定的命令而非 interactive shell,你仍需要通過一個 login shell 來運行,如:... /usr/bin/bash -lc python
。
shell 啟動腳本
在用戶主目錄中,有三個啟動腳本:
-
.bash_profile
- 啟動為 login shell 時被執行
- 該腳本中調用了
~/.bashrc
-
.profile
- 啟動為 login shell 時被執行,如果已存在
~/.bash_profile
或~/.bash_login
,則不執行 - 該腳本中調用了
~/.bashrc
- 啟動為 login shell 時被執行,如果已存在
-
.bashrc
- 啟動為交互式shell 時被執行
- 當僅啟動為 login shell 時,該腳本仍會被調用,但根據語句
[[ "$-" != *i* ]] && return
,該腳本將立即退出
可以發現以上腳本均不包含與子系統相關的內容,下面考察/etc
內的幾個啟動腳本:
msystem
- 該腳本由
profile
調用 - 環境變量
MSYSTEM
說明了啟動那個子系統,根據語句export MSYSTEM="${MSYSTEM:-MSYS}"
可知,若未指定MSYSTEM
,則默認為MSYS
- 根據
MSYSTEM
設置如下環境變量:MSYSTEM_PREFIX
MSYSTEM_CARCH
MSYSTEM_CHOST
MINGW_CHOST
MINGW_PREFIX
MINGW_PACKAGE_PREFIX
CONFIG_SITE
- 如果子系統為
MSYS
,則上述不包含前綴MINGW_
的變量
- 該腳本由
profile
- System-wide profile file
- 根據環境變量
MSYS2_PATH_TYPE
(默認為minimal
)設置環境變量ORIGINAL_PATH
,而后該變量將參與設置PATH
- 調用
/etc/msystem
- 根據
MSYSTEM
以及上一步中得到的環境變量,進一步設置環境,如PATH
,MANPATH
- 根據 shell(bash、ksh、zsh),調用
/etc/profile.d/
中的腳本
bash.bashrc
- System-wide bashrc file
CHERE_INVOKING
這是一個神秘的變量,通過設置該變量,可以使打開的 shell 保留當前工作目錄,而不是自動修改為用戶主目錄。在Starting in a particular directory中說明了這一作用。在msys2-launcher
的源碼和msys2_shell.cmd
中都可以看到該變量的身影。
但奇怪的是,我沒有在任何 shell 啟動腳本中找到這一變量,所以我不知道它在何處起了作用,但它又的的確確起了作用。
Windows 任務欄圖標
參考Taskbar icon grouping,任務欄上的圖標會根據圖標本身和啟動命令進行自動合並,也可通過設置AppID
來提供更優先的合並依據。
綜述
考慮到“開始”菜單里的快捷方式是安裝msys2
時自動創建的,所以這里就不再對其做出修改了。
綜上所述,得到注冊表文件如下:
Windows Registry Editor Version 5.00
[HKEY_CLASSES_ROOT\Directory\Background\shell\MSYS2]
"MUIVerb"="Open MSYS2 Here"
"Extended"=""
"SubCommands"="MSYS2.MSYS;MSYS2.MinGW 64-bit"
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\CommandStore\shell\MSYS2.MSYS]
"MUIVerb"="MSYS"
"Icon"="D:/msys64/msys2.ico"
; 開始的可執行文件路徑必須用反斜杠(back-slash)形式。盡管使用斜杠(slash)在資源管理器中
; 是有效的,但在注冊表中是無效的。
; mintty 的選項 --dir \"%V/\" 是沒有必要的。
; 這里的 title 和 msys2_shell.cmd 中的保持了一致。
; 將 env 放在前面也可以啟動,但會閃現黑框,這是因為 env 是命令行程序,需要在終端中執行,
; 而默認終端即為 cmd;而 mintty 為圖形程序。
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\CommandStore\shell\MSYS2.MSYS\command]
@="D:\\msys64\\usr\\bin\\mintty -i /msys2.ico -t \"MSYS2 MSYS\" /bin/env MSYSTEM=MSYS CHERE_INVOKING=1 /usr/bin/bash -li"
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\CommandStore\shell\MSYS2.MinGW 64-bit]
"MUIVerb"="MinGW 64-bit"
"Icon"="D:/msys64/mingw64.ico"
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\CommandStore\shell\MSYS2.MinGW 64-bit\command]
@="D:\\msys64\\usr\\bin\\mintty -i /mingw64.ico -t \"MinGW x64\" /bin/env MSYSTEM=MINGW64 CHERE_INVOKING=1 /usr/bin/bash -li"
巧的是,這樣一來,不論是從“開始”菜單中快捷方式啟動,還是從右鍵菜單中啟動,它們在任務欄上都被合並在了一起。