How to Pass MULTIPLE filenames to a Context Menu Shell Command?
Asked Answered
G

4

41

Passing a single filename to a context menu shell command is simple:

[HKEY_CLASSES_ROOT\*\shell\MyProgram\Command]
@="program.exe %1"

But if I select multiple files, program.exe is invoked for each such selected file.

What I would like to do instead is invokeprogram.exe only once, passing to it all the filenames currently selected.

How to do this?

Geanticline answered 22/6, 2011 at 13:33 Comment(1)
I've successfully added an item to file context-menu (HKEY_CLASSES_ROOT\*\shell). The item shows up when I right-click on a file. When I select multiple files and then right-click, it doesn't show up. How do I fix that?Bourbonism
E
9

You may want to look at this post, as it says that this isn't really possible to pass multiple files to a single instance and you must rely on some form of IPC(Inter process Communication).

Entablature answered 22/6, 2011 at 14:49 Comment(0)
V
34

You can use Send To for this. It supports multiple files.

In case this website goes offline:

Open shell:sendto with Windows + R or paste it into your explorer address bar. It should redirect you to:

C:\Users\<yourusername>\AppData\Roaming\Microsoft\Windows\SendTo

Create a shortcut to your program in this folder and you should see it in your explorer right-click menu under Send to

Vaniavanilla answered 24/6, 2015 at 10:30 Comment(4)
It seems there's a limit to how many files can be sent depending on the files' path. I can send 504 files with paths C:\test\001.txt. 504 file names amount to 7560 chars (no space), 8063 chars (space delimited). Sending 505 files (7575 chars [no space]; 8079 [space delimited]) doesn't work.Bourbonism
Saved me so much time. I use it for compare software.. ThanksPuzzler
When trying to pass the file G:\New [folder] (4)\Untitled-2.txt to a Powershell script, the result becomes G:\New [folder] 4 \Untitled-2.txt. It seems that parentheses cannot be parsed correctly. Any solution?Irresoluble
@Irresoluble try escaping parenths with a back tick: G:\New [folder] `(4`)\Untitled-2.txtFylfot
E
9

You may want to look at this post, as it says that this isn't really possible to pass multiple files to a single instance and you must rely on some form of IPC(Inter process Communication).

Entablature answered 22/6, 2011 at 14:49 Comment(0)
R
1

I created a small program that completely solves this problem. https://github.com/ge9/ExecuteCommand-Pipe

It is based on this Microsoft sample code: https://github.com/microsoft/Windows-classic-samples/tree/main/Samples/Win7Samples/winui/shell/appshellintegration/ExecuteCommandVerb

It uses COM (Component Object Model) technology of Windows, so there are no restriction on the number or path length of passed files. Also it doesn't involve any inter-process communication, preserving the order of files. The command for opening files is specified in registry values. See the repository for details.

Redeploy answered 7/12, 2023 at 11:54 Comment(1)
While this link may answer the question, it is better to include the essential parts of the code here and provide the link for reference. Link-only answers can become invalid if the linked page changes.Edgebone
F
0

Use: Command-Queuer.cmd

I wanted to do the same thing and ended up creating a 'wrapper' .cmd/bat file to queue the commands for me... I use a temporary queue file to: (a) self-nominate a control instance to run the process, and (b) signal to other instances not run the command(s) directly and instead just add their file/parameters to the queue and exit. The script waits X seconds for the other instances to queue their info and then processes the selected files sequentially.

Command-Queuer.cmd
------------------

@ECHO OFF
SETLOCAL

:: SETUP PARAMETERS: Control temp file location and delay before running
SET QueueFile="%TEMP%\Multi-Item-Queue.txt"
SET /A Secs=5

:: MAIN PROGRAM: If the first instance create the queue and wait, otherwise transfer to queue and exit
IF EXIST %QueueFile% ( ECHO %* >> %QueueFile% ) ELSE (
    ECHO %* > %QueueFile%
    ECHO Waiting %Secs% seconds for other files to finish queuing then will activate...
    TIMEOUT /T %Secs% /NOBREAK >nul
    
    REM - ADD YOUR CODE HERE TO PROCESS THE QUEUE FILE AS A WHOLE
    REM - Example: Display popup of all file paths selected: Msg %username% <%QueueFile%
    
    REM - ALTERNATIVELY, ITERATE THROUGH EACH LINE OF THE FILE
    REM - Example: FOR /F "tokens=*" %%Z in (%QueueFile%) DO ( COPY %%Z "C:\Backup" )
    
    :: Delete the queue file when finished
    DEL %QueueFile%
)
GOTO:EOF

NOTE: You will see a empty cmd window appear for a split-second for each file selected, i.e. if you select 30 files then 30 cmd windows will briefly appear, but these can be hidden if desired please check: Run a batch file in a completely hidden way (superuser.com)

Front answered 15/5, 2023 at 7:55 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.