Search code examples
windowsbatch-fileactionfile-type

pass two files to a windows file type action


Using Windows XP, I created a batch-file that takes two files as arguments, and now I want to add a file-type action "compare" to specific extensions, e.g. ".txt" that calls the batch-file with two selected files. That is I want to select two ".txt" files, and then select "compare" from the shell context menu and have it execute the batch-file with those two files.

I can easily add the "compare" action to the "Text Document" file-type, and select the batch-file with two arguments, e.g. "C:\batch.bat" "%1" "%2" (btw: this works fine from cmd and in other programs, e.g. Git difftool), but then if I select 2 files and try compare them, Windows opens two separate instances for each of the two selected files instead of comparing them.

I checked google and SO but could not find any reference of how to obtain the files as arguments to pass to the file-type action. Thanks!


Solution

  • This question is a duplicate. It is addressed here: How to pass in multiple file/folder paths via a right-click event (verb) to an executable?

    and here: How to add new items to right-click event on Folders and Files in Windows?

    and is similar to this unanswered question on superuser: Creating Context Menu Item For Multiple Files

    In a nutshell, when you select 2 files and then choose an action from the context menu (a "verb" in windows shell parlance), windows will always open 2 seperate instances, unless your application has a check to see if it is already running. The trick then is to include in your application (the batch file in my case) an alternate method to execute. This can be achieved as Factor Mystic and Remy Lebeau - TeamB both point out by using an Interprocess Communication (IPC) such as Dynamic Data Exchange (DDE). Factor Mystic also list some good MSDN references for this. Also there is a quick and dirty way suggested by lowlevel using SendTo.

    Here's my quick and dirty way:

    @ECHO off
    SETLOCAL
    IF NOT EXIST C:\file.tmp (
        ECHO %1 > C:\file.tmp
    ) ELSE (
        FOR /F "TOKENS=*" %%A IN (C:\file.tmp) DO (
            DEL C:\file.tmp
            C:\BATCH %1 %%A
        )
    )
    SETLOCAL
    

    This is the application I use for the file-type action "verb" and it only takes one variable. I did not use DDE, because I cache the first file on the drive. Then call the real application (BATCH) from the first one, once I have both files. Obviously it has problems when odd #s of files are called, but like I said it's quick and dirty.

    Anyway, I'm closing this since I believe there is an abundance of info on how to solve this the correct way.