如何创建一个以多个文件作为参数的 shell 上下文菜单项?

如何创建一个以多个文件作为参数的 shell 上下文菜单项?

创建以单个文件作为参数的 Windows Shell 上下文菜单项很容易。请参阅这个问题举个例子。

但是,如何创建一个以多个文件为参数的上下文菜单项?比如,对于 diff-merge 工具(在我的情况下是 P4Merge),尽管同样的技术无疑也适用于其他应用程序。

我已经安装了 P4Merge,但它不会自动将项目添加到上下文菜单中,所以我必须手动执行此操作。

当我尝试使用时:

"C:\Program Files\Perforce\p4merge.exe" %1 %2

作为命令行我收到一个错误:

错误:至少需要两个文件。无法仅打开一个文件。P4Merge 需要 0、2 或 3 个文件。

当我尝试使用时:

"C:\Program Files\Perforce\p4merge.exe" %0 %1

作为命令行,它打开了两个 P4Merge 实例,每个文件一个。

看起来正确的文件名被传递给了 %0 和 %1,但是每个文件名都执行了不同的 P4Merge 应用程序实例。

我目前有 SourceGear 的 DiffMerge 工具,它在 Shell 上下文菜单上有一个项目,并且工作得很好,因为我可以选择两个文件并使用上下文菜单项对它们运行比较。我尝试搜索注册表以查看 DiffMerge 使用的参数,但我找不到包含参数的 DiffMerge 命令行。

答案1

您也可以尝试将该程序添加到 SendTo 菜单。

答案2

浏览答案后发现似乎没有简单的解决方法,需要 shell 扩展。再次查看 DiffMerge 的注册表项,它似乎使用了一个 shell 扩展:DiffMergeShellExtension64.dll。如果 P4Merge 没有这样的 shell 扩展,那么看起来我唯一能让它在 Windows 资源管理器上下文菜单中正常工作的方法就是自己编写一个。

编写 Shell 扩展的完整指南Code Project 中的系列是编写 shell 扩展的实用指南。该系列的第二部分是关于编写一个可以同时处理多个文件的扩展(这正是我需要的)。

警告:《编写 Shell 扩展的完整指南》使用 C 和 COM、ATL(活动模板库)和 MFC(Microsoft Foundation Classes)。因此,如果您不熟悉这些技术,编写 Shell 扩展将是一个漫长且可能很困难的过程;这绝对不是一小时内就能完成的事情。

答案3

你可以用我的程序来做上下文菜单启动器(单实例)

Windows Registry Editor Version 5.00

[HKEY_CLASSES_ROOT\SystemFileAssociations\.txt\Shell\p4merge]
"MultiSelectModel"="Player"

[HKEY_CLASSES_ROOT\SystemFileAssociations\.txt\Shell\p4merge\Command]
@="\"d:\\singleinstance.exe\" %1 \"C:\\Program Files\\Perforce\\p4merge.exe\" $files --si-timeout 400"

答案4

概括

  1. 在注册表中将目标程序设置为上下文菜单创建文件.exe写道注册表文件文件。

  2. 在主程序中每 1 秒循环检查一次注册表文件存在。如果存在,则终止上下文菜单创建文件.exe并删除注册表文件文件。然后复制选定的文件路径并对其进行操作。

  3. 如果你的程序循环检查注册表文件,那么您需要在启动时或手动执行上下文菜单之前启动该程序。

我这样做了自动热键

下面这两个 AutoHotkey 脚本允许您在 Windows 资源管理器中添加P4 Merge Compare上下文菜单项以打开多个选定的文件。

您可以保留所有变量值,但如果您想更改值contextMenuprogram名称,请参阅3.1.

指示:

在同一目录中创建2个文件:

  1. 创建第一个程序添加到上下文菜单并创建启动快捷方式.ahk

    1. RunAsAdmin标签确保脚本以管理员身份运行(修复添加注册表值)。

      1. 检查If (!A_IsAdmin)当前用户是否不是admin,A_IsAdmin 是内置的 AutoHotkey 变量,如果用户是管理员则返回 1,否则返回 0。
      2. Run, \*RunAs "%A_ScriptFullPath%" *运行方式参数以管理员身份运行脚本,“%A_ScriptFullPath%”获取当前执行脚本的完整路径。
      3. ExitApp退出当前以非管理员权限运行的脚本实例。
      4. 因为该Run命令以管理员权限再次运行脚本,所以它将跳过IF条件并继续执行下面的代码。
    2. ContextMenuCreateFile:标签创建上下文菜单创建文件.exe创建一个文件注册表文件并退出上下文菜单创建文件.exe写入文件后注册表文件. 确保在命令Ahk2Exe.exe中指定路径的位置RunWait

    3. Add To Context Menu:标签添加运行的注册表项上下文菜单创建文件.exe

      1. 将变量设置contextMenu为需要在上下文菜单中显示的内容。(名称program设置为contextMenu
      2. 设置regPath为您想要的注册表路径。
      3. 当它执行时MsgBox,检查命令是否添加到地址栏中的注册表中。
    4. CreateStartupShortcut:Label创建主程序的快捷方式P4 合并比较.exe在启动文件夹中。

添加到上下文菜单并创建启动快捷方式.ahk

; =============Recommended Settings=============
#NoEnv
SetWorkingDir %A_ScriptDir%
#Warn
CoordMode, Mouse, Window
SendMode Input
#SingleInstance Force
SetTitleMatchMode 2
SetTitleMatchMode Fast
DetectHiddenWindows Off
DetectHiddenText On
#WinActivateForce
#NoTrayIcon
SetControlDelay 1
SetWinDelay 0
SetKeyDelay -1
SetMouseDelay -1
SetBatchLines -1
#Persistent
#MaxThreadsPerHotkey 2
; =============Recommended Settings=============

AddToContextMenuAndCreateStartupShortcut:
RunAsAdmin:  ; =============RunAsAdmin=============
If (!A_IsAdmin)  ; IF NOT Admin
{
    Run, *RunAs "%A_ScriptFullPath%"  ; Run script as admin
    ExitApp  ; Exit the current instance running without admin privileges
}
ContextMenuCreateFile:  ; =============ContextMenuCreateFile=============
contextMenuCreateFileAhk := 
(LTrim
"#NoEnv
#NoTrayIcon
#SingleInstance Force
SetWorkingDir %A_ScriptDir%
SetBatchLines -1

ContextMenuCreateFile:
FileDelete, reg.txt
FileAppend, , reg.txt
ExitApp
Return"
)  ; contextMenuCreateFileAhk
FileDelete, Context Menu Create File.exe  ; DEL Context Menu Create File.exe
FileDelete, Context Menu Create File.ahk  ; DEL Context Menu Create File.ahk
FileAppend, %contextMenuCreateFileAhk%, Context Menu Create File.ahk  ; MAKE Context Menu Create File.ahk
RunWait, C:\Program Files\AutoHotkey\Compiler\Ahk2Exe.exe /in "Context Menu Create File.ahk" /out "Context Menu Create File.exe"  ; Convert AHK to EXE
FileDelete, Context Menu Create File.ahk  ; DEL Context Menu Create File.ahk
AddToContextMenu:  ; =============AddToContextMenu=============
path := ""  ; path
program := "Context Menu Create File"  ; program
contextMenu := "P4 Merge Compare"  ; contextMenu
regPath := "HKCR\*\shell"  ; regPath
StringReplace, regKey, contextMenu, %A_Space%, , A  ; regKey
regKey := 0 regKey  ; regKey
Loop, Files, %program%.exe, F  ; Find Program.exe In Current Dir
{
    path := A_LoopFileLongPath  ; Set Program Path
}
cmd := 
(LTrim
"reg add """ regPath "\" regKey """ /ve /t REG_SZ /d """ contextMenu """ /f
reg add """ regPath "\" regKey "\command"" /ve /t REG_SZ /d ""\""" path "\""`"" /f"
)  ; Registry
FileDelete, Add To Context Menu.bat  ; CREATE Add To Context Menu.bat
FileAppend, %cmd%, Add To Context Menu.bat  ; CREATE Add To Context Menu.bat
RunWait, Add To Context Menu.bat, , Hide  ; RUN Add To Context Menu.bat (*RunAs ADMIN)
FileDelete, Add To Context Menu.bat  ; DEL Add To Context Menu.bat
Run, regedit  ; regedit
WinWait, Registry Editor ahk_class RegEdit_RegEdit ahk_exe regedit.exe  ; Registry
Sleep, 333
ControlSetText, Edit1, %regPath%\%regKey%\command, Registry Editor ahk_class RegEdit_RegEdit ahk_exe regedit.exe  ; regPath
ControlFocus, Edit1, Registry Editor ahk_class RegEdit_RegEdit ahk_exe regedit.exe  ; regPath
ControlSend, Edit1, {Enter}, Registry Editor ahk_class RegEdit_RegEdit ahk_exe regedit.exe  ; regPath
ControlSend, SysListView321, {Control Down}{NumpadAdd}{Control Up}, Registry Editor ahk_class RegEdit_RegEdit ahk_exe regedit.exe  ; regPath
ControlSend, SysListView321, {F5}, Registry Editor ahk_class RegEdit_RegEdit ahk_exe regedit.exe  ; regPath
MsgBox, 262192, CHECK, Check If Added %contextMenu% To Registry  ; CHECK
CreateStartupShortcut:  ; =============CreateStartupShortcut=============
path := ""  ; path
program := contextMenu  ; program
Loop, Files, %program%.exe, F  ; Find Program.exe In Current Dir
{
    path := A_LoopFileLongPath  ; Set Program Path
}
FileCreateShortcut, %path%, %A_Startup%\%program%.lnk  ; Create Startup Shortcut
Run, %A_Startup%, , Max  ; Check If Shortcut Created
Run, "%program%.exe"  ; Run Program
MsgBox, 262144, CHECK, Check If Shortcut Created  ; CHECK
ExitApp  ; ExitApp
Return
  1. 创建第二个程序P4 合并比较.ahk这是主程序。
    1. 这里Loop创建了一个 a,并每隔 1 秒检查一次注册表文件存在。
    2. IfExist, reg.txt它杀死了上下文菜单创建文件.exe并删除注册表文件
    3. 然后它激活 explorer.exe 窗口并将所有选定的文件路径复制到剪贴板
    4. If CLIPBOARD contains .,\确保;确定剪贴板包含路径“\”带延伸“。”
    5. 选定文件的列表保存在selectedFiles变量中。
    6. 下面的循环p4Params := ""循环遍历选定的文件,获取filePaths。
    7. 然后将filePath连接到p4Params
    8. StringTrimRight从字符串中删除最后一个空格p4Params
    9. 然后Run, C:\Program Files\Perforce\p4merge.exe %p4Params%使用%p4Params%(选定文件列表)执行。

P4 合并比较.ahk

; =============Recommended Settings=============
#NoEnv
SetWorkingDir %A_ScriptDir%
#Warn
CoordMode, Mouse, Window
SendMode Input
#SingleInstance Force
SetTitleMatchMode 2
SetTitleMatchMode Fast
DetectHiddenWindows Off
DetectHiddenText On
#WinActivateForce
#NoTrayIcon
SetControlDelay 1
SetWinDelay 0
SetKeyDelay -1
SetMouseDelay -1
SetBatchLines -1
#Persistent
#MaxThreadsPerHotkey 2
; =============Recommended Settings=============

P4MergeCompare:
Loop  ; Loop Start
{
    Sleep, 1000  ; Fix High CPU
    IfExist, reg.txt  ; IF reg.txt EXIST
    {
        RunWait, cmd /c taskkill /im "Context Menu Create File.exe" /f, , Hide  ; Fix Opening 2 Compose Windows
        FileDelete, reg.txt  ; DEL reg.txt
        WinActivate, ahk_class CabinetWClass ahk_exe explorer.exe  ; Explorer
        CLIPBOARD := ""  ; Clear Clipboard
        Send, {Control Down}{c}{Control Up}  ; Copy File Paths
        ClipWait, 0  ; Clip Wait
        If CLIPBOARD contains .,\  ; IF CLIPBOARD contains .,\
        {
            selectedFiles := CLIPBOARD  ; selectedFiles
            p4Params := ""  ; p4Params
            Loop, Parse, selectedFiles, `n, `r  ; Loop Start selectedFiles
            {
                filePath := """" A_LoopField """"  ; filePath
                p4Params .= filePath . " "  ; p4Params .= %filePath%,
            }
            StringTrimRight, p4Params, p4Params, 1  ; Remove Last Space
            Run, C:\Program Files\Perforce\p4merge.exe %p4Params%  ; Open Files In P4Merge
        }
    }
}
Return
  1. 转换两者添加到上下文菜单并创建启动快捷方式.ahkP4 合并比较.ahkEXE文件使用同一目录中的文件Ahk2Exe 工具-->(在开始菜单中找到,只需浏览文件并点击转换)

  2. 执行Add To Context Menu And Create Startup Shortcut.exe

  3. 选择文件,右键单击,然后P4 合并比较应该出现上下文菜单项。

相关内容