matf-pp / 2019_Windows_copy

0 stars 3 forks source link

MultiSelectModel vs MultipleInvokePromptMinimum #1

Closed glachancecmaisonneuve closed 5 years ago

glachancecmaisonneuve commented 5 years ago

I stumbled on your project while looking for something else and I thought I should take a minute to point out that changing MultipleInvokePromptMinimum to a different value will impact every context menu that has not declared a MultiSelectModel in it's verb, along with all the ones that declared "MultiSelectModel"="Document" in their verb.

The solution you are looking for, that only affects your own context menu, is a registry entry named MultiSelectModel. It has 3 possible values, "Single", "Document" or "Player".

"MultiSelectModel"="Document" is default, and once the number of items selected is greater than the value in set in MultipleInvokePromptMinimum (usually 15), the menu is not shown.

If you want your context menu to be shown when the number of items selected items is greater than the value set in MultipleInvokePromptMinimum, all you need to do is to set "MultiSelectModel"="Player" on your verb.

[HKEY_CLASSES_ROOT\YourProgId\shell\YourVerb]
@="My Verb Text"
"MultiSelectModel"="Player"
[HKEY_CLASSES_ROOT\YourProgId\shell\YourVerb\command]
@="YourApp.exe"

ref: https://docs.microsoft.com/en-us/windows/desktop/shell/how-to-employ-the-verb-selection-model

Jovan-Zan commented 5 years ago

@glachancecmaisonneuve Thank you for your time and suggestion. We are aware of this issue. We have tried what you have suggested, but we got something wrong and the option "RoboCopyV2" doesn't get displayed at all.

Other programs, VLC media player and WinRar for example, use the approach you suggested, we checked it in the registry. Even when we try to mirror their key and value entries, "RoboCopyV2" doesn't get displayed in the context menu.

Below is the code of NSIS (Nullsoft Scriptable Install System) script which creates installer, which in turn modifies the registry. It's easy to read.

We will be very grateful if you could help us fix this issue. Thank you again!

;---Installation script

    !define APP_NAME "MultithreadWindowsCopy"

; Include Modern UI
    !include "MUI2.nsh"

; Includes KillProcess
    !include "nsProcess.nsh"

; Includes if statement
    !include LogicLib.nsh

; Includes runningX64
    !include x64.nsh

;------------------------------

; The name of the installer
    Name "${APP_NAME}"

; The output file
    OutFile "MultithreadWindowsCopyInstaller.exe"

; The default installation directory
    InstallDir  "$PROGRAMFILES\${APP_NAME}"

; Registry key to check for directory (so if installed again, it will 
; overwrite the old one automatically)
    InstallDirRegKey HKLM "Software\${APP_NAME}" "InstallDir"

; Administrator privileges are needed to install to ProgramFiles directory
    RequestExecutionLevel admin

;------------------------------

; Prompt a warning when user tries to cancel installation.
    !define MUI_ABORTWARNING    

;------------------------------

; Pages user goes through when installing
    !insertmacro MUI_PAGE_DIRECTORY
    !insertmacro MUI_PAGE_INSTFILES  

;------------------------------

; Uninstall pages
    !insertmacro MUI_UNPAGE_CONFIRM
    !insertmacro MUI_UNPAGE_INSTFILES

;------------------------------

; On installation initialization, set registry view to x64 if running x64
Function .onInit
  ${If} ${RunningX64}
    SetRegView 64
  ${EndIf}
FunctionEnd

;------------------------------

Section ""

; Set output path to the installation directory.
    SetOutPath $INSTDIR

; Put files
    File "CopyApp.exe"
    File "CopyApp.exe.config"
    File "PasteApp.exe"
    File "PasteApp.exe.config"
    File "ClipboardApp.exe"
    File "ClipboardApp.exe.config"  

; GIT ISSUE TRY TO RESOLVE
    ;[HKEY_CLASSES_ROOT\YourProgId\shell\YourVerb]
    ;@="My Verb Text"
    ;"MultiSelectModel"="Player"
    ;[HKEY_CLASSES_ROOT\YourProgId\shell\YourVerb\command]
    ;@="YourApp.exe"
    WriteRegStr HKCR "${APP_NAME}\shell\RoboCopyV2" "" "Robo-Copy v2"
    WriteRegStr HKCR "${APP_NAME}\shell\RoboCopyV2" "MultiSelectModel" "Player"
    WriteRegStr HKCR "${APP_NAME}\shell\RoboCopyV2\command" "" '"$INSTDIR\CopyApp.exe" "copy"'

; Save installation folder to registry
    WriteRegStr HKLM "Software\${APP_NAME}" "InstallDir" "$INSTDIR"  

; Add Robo-Copy command
    WriteRegStr HKCR "Directory\shell\Robo-Copy\command" "" '"$INSTDIR\CopyApp.exe" "copy"'
    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;WriteRegDWORD HKCU "Software\Microsoft\Windows\CurrentVersion\Explorer" "MultipleInvokePromptMinimum" 16
    ; This is for folder right click menu
    WriteRegStr HKCR "*\shell\Robo-Copy\command" "" '"$INSTDIR\CopyApp.exe" "copy"'

; Add Robo-Cut command
    WriteRegStr HKCR "Directory\shell\Robo-Cut\command" "" '"$INSTDIR\CopyApp.exe" "cut"'
    WriteRegStr HKCR "*\shell\Robo-Cut\command" "" '"$INSTDIR\CopyApp.exe" "cut"'

; Add Robo-Paste command
    WriteRegStr HKCR "Directory\Background\shell\Robo-Paste\command" "" '"$INSTDIR\PasteApp.exe" "%v"' 

; Set "hide file name extensions" to false
    WriteRegDWORD HKCU "Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced" "HideFileExt" 0

; Write the uninstall keys for Windows
    WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APP_NAME}" "DisplayName" "${APP_NAME}"
    WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APP_NAME}" "UninstallString" '"$INSTDIR\uninstall.exe"'
    WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APP_NAME}" "NoModify" 1
    WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APP_NAME}" "NoRepair" 1

; Write the uninstaller
    WriteUninstaller "$INSTDIR\uninstall.exe"
SectionEnd

;------------------------------

; On UNinstallation initialization, set registry view to x64 if running x64
Function un.onInit
  ${If} ${RunningX64}
    SetRegView 64
  ${EndIf}
FunctionEnd

;------------------------------

Section "Uninstall"
; Kill ClipboardApp.exe before uninstallation and save result in registry R0
    ${nsProcess::KillProcess} "ClipboardApp.exe" $R0

; GIT ISSUE
    DeleteRegKey HKCR "${APP_NAME}"

; Delete registry keys and values
    DeleteRegKey HKLM "Software\${APP_NAME}"
    DeleteRegKey HKCR "Directory\shell\Robo-Copy"
    DeleteRegValue HKCU "Software\Microsoft\Windows\CurrentVersion\Explorer" "MultipleInvokePromptMinimum"
    DeleteRegKey HKCR "*\shell\Robo-Copy"
    DeleteRegKey HKCR "Directory\shell\Robo-Cut"
    DeleteRegKey HKCR "*\shell\Robo-Cut"
    DeleteRegKey HKCR "Directory\Background\shell\Robo-Paste"
    DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APP_NAME}"

; Delete files
    Delete "$INSTDIR\CopyApp.exe"
    Delete "$INSTDIR\CopyApp.exe.config"
    Delete "$INSTDIR\PasteApp.exe"
    Delete "$INSTDIR\PasteApp.exe.config"
    Delete "$INSTDIR\ClipboardApp.exe"
    Delete "$INSTDIR\ClipboardApp.exe.config"
    Delete "$INSTDIR\uninstall.exe"

; Delete directories used
    RMDir $INSTDIR

SectionEnd
glachancecmaisonneuve commented 5 years ago
Windows Registry Editor Version 5.00

[HKEY_CLASSES_ROOT\Directory\shell\RoboCopyV2]
@="RobocopyV2"
"ExtendedSubCommandsKey"="RobocopyV2PasteSubMenu"
"Icon"="\"C:\\Program Files\\RobocopyV2\\MoveApp.exe\""
"NeverDefault"=""

[HKEY_CLASSES_ROOT\Directory\Background\shell\RoboCopyV2]
"ExtendedSubCommandsKey"="RobocopyV2PasteSubMenu"
"Icon"="\"C:\\Program Files\\RobocopyV2\\MoveApp.exe\""
"NeverDefault"=""

[HKEY_CLASSES_ROOT\AllFilesystemObjects\shell\RobocopyCopySelectedFiles]
"Icon"="\"C:\\Program Files\\RobocopyV2\\CopyApp.exe\""
"NeverDefault"=""
"MultiSelectModel"="Player"
@="Prep Copy"
"ShowAsDisabledIfHidden"=""
"AttributeMask"=dword:00000001
"AttributeValue"=dword:00000001

[HKEY_CLASSES_ROOT\AllFilesystemObjects\shell\RobocopyCopySelectedFiles\command]
@="\"C:\\Program Files\\RobocopyV2\\CopyApp.exe\" \"%1\""

[HKEY_CLASSES_ROOT\RobocopyV2PasteSubMenu\shell]
"Display"="RoboCopyV2Copy,RoboCopyV2Move"

[HKEY_CLASSES_ROOT\RobocopyV2PasteSubMenu\shell\RoboCopyV2Copy]
@="Robocopy the files here (copy)"
"Icon"="\"C:\\Program Files\\RobocopyV2\\MoveApp.exe\""
"AttributeMask"=dword:00000001
"AttributeValue"=dword:00000001
"MultiVerbSelectionModel"="Player"
"NeverDefault"=""

[HKEY_CLASSES_ROOT\RobocopyV2PasteSubMenu\shell\RoboCopyV2Copy\Command]
@="\"C:\\Program Files\\RobocopyV2\\MoveApp.exe\" --copyoperation"

[HKEY_CLASSES_ROOT\RobocopyV2PasteSubMenu\shell\RoboCopyV2Move]
@="Robocopy the files here (copy) (move)"
"Icon"="\"C:\\Program Files\\RobocopyV2\\MoveApp.exe\""
"AttributeMask"=dword:00000002
"AttributeValue"=dword:00000002
"MultiVerbSelectionModel"="Player"
"NeverDefault"=""
"HasLUAShield"=""

[HKEY_CLASSES_ROOT\RobocopyV2PasteSubMenu\shell\RoboCopyV2Move\Command]
@="\"C:\\Program Files\\RobocopyV2\\MoveApp.exe\" --moveoperation"
glachancecmaisonneuve commented 5 years ago

I had 15000+ items selected at the time:

image

This is the submenu: image

glachancecmaisonneuve commented 5 years ago

I'm not too sure why you have a "copy app" though. Why not let the user use the system copy and have only a paste app (moveapp.exe).

glachancecmaisonneuve commented 5 years ago

The short version of all of this would have been that you are not writing the MultiVerbSelectionModel at the right place, it goes on the verb