Keyboard shortcut for 7z "Add to archive..."

I want to create a keyboard shortcut for the Right click > Add to archive... feature of 7z, in the Windows File Explorer.

This nearly works with AutoHotkey:

#z::
    SendInput {AppsKey}a{Enter}
    Return

Indeed APPSKEY then A is sometimes okay:

enter image description here

but sometimes not okay, for example, when the selected file is a Folder:

enter image description here

for which another menu item would be selected for the letter "A" (here, "Add to MPC-HC playlist").

Important notes:

  • I could manually find in regedit.exe the various Context menu items for Files, for Folders, for every possible File extension (too many possible extensions!), but this would be too long... wouldn't it? (*)

  • I already tried with a "Cascaded context menu" for 7z (this is available in the 7z-File-manager > Tools > Options... > 7-Zip menu), but things are even worse. Depending on the context, the letter are not the same and then it's impossible to associate a consistent hotkey

  • A solution would be that 7z would register &Add to archive... instead of just Add to archive... in the context menus. If I remember well & in the regedit context menu settings is what helps the context menu to use a letter shortcut. Is there an option for this? Sadly this doesn't seem available directly in 7-zip.


(*) Would it be still possible with few regedit editions? i.e. replace Add to archive... by &Add to archive? In how many keys/values should this be done? In:

HKEY_CLASSES_ROOT\Folder\ShellEx\ContextMenuHandlers\7-Zip

I see:

{23170F69-40C1-278A-1000-000100020000}

Can this be useful?


Solution 1:

Try this

#IfWinActive ahk_class CabinetWClass    ; explorer

    #z::
        ClipSaved := ClipboardAll       ; save the entire clipboard to the variable ClipSaved
        clipboard := ""                 ; empty the clipboard (start off empty to allow ClipWait to detect when the text has arrived)
        Send, ^c                        ; copy selected item
        ClipWait, 1                     ; wait for the clipboard to contain data 
        if (!ErrorLevel)                ; If NOT ErrorLevel ClipWait found data on the clipboard
        {
            ; MsgBox, %clipboard%       ; display the path
            FileGetAttrib A, %clipboard%
            if InStr(A, "D")            ; is a folder
                SendInput {AppsKey}aa{Enter}
            else                        ; is a file
                SendInput {AppsKey}a{Enter}
        }
        else
            MsgBox, No file selected
        Sleep, 300 
        clipboard := ClipSaved         ; restore original clipboard
        VarSetCapacity(ClipSaved, 0)   ; free the memory
    return

#IfWinActive

https://www.autohotkey.com/docs/commands/_IfWinActive.htm https://www.autohotkey.com/docs/misc/Clipboard.htm#ClipboardAll https://www.autohotkey.com/docs/commands/FileGetAttrib.htm

EDIT

This should work if we select multiple files to ZIP:

#IfWinActive ahk_class CabinetWClass    ; explorer

    #z::
        folder := false
        file := false
        ClipSaved := ClipboardAll       ; save the entire clipboard to the variable ClipSaved
        clipboard := ""                 ; empty the clipboard (start off empty to allow ClipWait to detect when the text has arrived)
        Send, ^c                        ; copy selected item
        ClipWait, 1                     ; wait for the clipboard to contain data 
        if (!ErrorLevel)                ; If NOT ErrorLevel ClipWait found data on the clipboard
        {
            Loop, Parse, Clipboard, `n  ; split by linefeed
            {
                LoopField := trim(A_LoopField, "`r`n") ; trim CRs/LFs
                FileGetAttrib A, %LoopField%
                if InStr(A, "D")        ; is a folder
                    folder := true
                else                    ; is a file
                    file := true
            }
            if (folder) 
            {
                if (file)              ; folders and files
                    SendInput {AppsKey}a{Enter}
                else                   ; only folders
                    SendInput {AppsKey}aa{Enter}
            }
            else if (file)             ; only files     
                SendInput {AppsKey}a{Enter}
        }
        else
            MsgBox, No file selected
        Sleep, 300 
        clipboard := ClipSaved         ; restore original clipboard
        VarSetCapacity(ClipSaved, 0)   ; free the memory
    return
    
#IfWinActive