[msys2]集成到右鍵菜單


集成到右鍵菜單

如有錯誤,歡迎指出

在資源管理器中,空白處右鍵(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)右擊,彈出菜單的內容。

image-20210220211323843

這里根據子項cmd,做一個簡單的解釋:

cmd

cmd\command

Extended,空值,擁有該數據項意味着當按住shift鍵右擊時,才可看到該菜單項,否則按住shift與否,均可看到;

HideBasedOnVelocityId,查看Powershell可發現其擁有ShowBasedOnVelocityId,這兩個數據項決定了,誰隱藏,誰顯示;

MUIVerb:菜單項的顯示文本。如果沒有該數據項,則顯示(默認)數據項的值(雖然在cmd中,看起來很奇怪),如果(默認)未設置值或為空值,則顯示為項名稱;

command子項,(默認)數據項:即為要執行的命令,其中%V表示當前目錄,是注冊表內置的變量;

若傳遞了錯誤的注冊表變量,甚至會導致 explorer.exe 進程重啟。

此外,可以參考 https://superuser.com/questions/136838/which-special-variables-are-available-when-writing-a-shell-command-for-a-context

Icon.ico圖標文件的路徑;

SubCommands:二級菜單項列表,用;分隔,對應實體位於HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\CommandStore\shell\中。

有趣的是,當(默認)被設置為空值或其它值后,可以看到標志着存在二級菜單的>,但卻無法彈出二級菜單;另外,如果列表中對應的項不存在,也同樣無法彈出二級菜單。

image-20210221001313520

啟動方式

在開始菜單中,有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中,還有一些其它方案:

事實上,上面的幾個方案最終都調用了mintty.exe

最終方案

上面已經說明了如何通過修改注冊表添加右鍵菜單,並給出了msys2的一種啟動方式,但該方法並不完美。

The idea

Lauchers的最后,The idea部分,說到:

如果你需要正確啟動一個shell,但上面提及的方法中又沒有適合的,那么可以基於下面的知識來制定你自己的方法:

  • 在環境中設置MSYSTEM=...,其值可為MSYSMINGW32,或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
  • .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以及上一步中得到的環境變量,進一步設置環境,如PATHMANPATH
    • 根據 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"

巧的是,這樣一來,不論是從“開始”菜單中快捷方式啟動,還是從右鍵菜單中啟動,它們在任務欄上都被合並在了一起。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM