Is it possible to use a shell script in the sendto folder?

8

2

I would like to use a bash shell script from the SendTo folder. When I put a shortcut to a batch or exe into theSendTo folder it shows up in the shell Send To context submenu, but when the shortcut is pointing at a shell script it doesn't.

The OS I'm testing this on is Win7 Home Premium SP1. The extension is .sh which has been associated with MinGW's bash.exe.

My shell script has a .sh extension and I've tried disassociated the .sh extension (I think that MinGW set it up initially, but that didn't work) using this utility and tried to reassociate it to bash using:

ftype ShellScript=c:\MinGW\msys\1.0\bin\bash.exe -c "'%1' %2"
assoc .sh=ShellScript

in an admin cmd shell. Though this works at a command prompt and the Explorer shell (via double click), it won't show up in the Send To menu and it won't accept a parameter by dragging a file on top of the script directly.

Does anyone know how I would do this?

Adrian

Posted 2013-06-18T08:35:22.343

Reputation: 364

1Does Explorer run the bash shell script if you double click the shortcut to the shell script? Is the shortcut just for the shell script or for bash parameterized with the shell script? – Werner Henze – 2013-06-18T09:50:20.223

what is the file extension of the script? have you established a file type association for that type? windows cannot process the bang line if it is present. which bash-for-windows are you using? – Frank Thomas – 2013-06-18T12:05:08.147

@FrankThomas: I've added the additional info you requested to the question. – Adrian – 2013-06-18T13:31:41.520

@WernerHenze: An attempt to drag a file over a link to the script causes a red circle with cross to appear. Attempting to put it directly over the script doesn't work either (says Move to *dir*), so I'm thinking that it's not taking parameters for some reason even though it is executed if double clicked on. Any idea why this would be so? – Adrian – 2013-06-18T13:49:29.540

I don't find the answer to Werner Henze's second question, so in the similar direction: Did you try to use c:\MinGW\msys\1.0\bin\bash.exe -c C:\Path\To\Your\Script.sh as the target for the shortcut in SendTo? – mpy – 2013-06-24T07:04:55.317

@mpy, WernerHenze: Sorry, I think I assumed that the 2nd question had an inferred answer given ftype ShellScript=c:\MinGW\msys\1.0\bin\bash.exe -c "'%1' %2" which shows parameters being passed. So yes, it's for a parametrised shell script. – Adrian – 2013-06-24T12:03:32.380

@mpy: Yes, I had tried c:\MinGW\msys\1.0\bin\bash.exe -c C:\Path\To\Your\Script.sh as the target for the shortcut in SendTo is because I need to control how the parameters are laid out on the command line. -c requires a single string to be passed as the command to be invoked. Any whitespace that is not quoted results in it being considered as the next parameter for bash, not the shell script. – Adrian – 2013-06-24T12:36:38.487

(which BTW, seems contrary to the man page: -c string If the -c option is present, then commands are read from string. If there are arguments after the string, they are assigned to the positional parameters, starting with $0.) – Adrian – 2013-06-24T12:37:01.550

Thank you to @mpy for explaining what that man page quote actually means. I totally misinterpreted what it meant. – Adrian – 2013-06-24T17:55:50.037

Answers

4

This will enable Drag & Drop to any script. You can place one of them in SendTo folder and use it afterwards.

Registry Export:

Windows Registry Editor Version 5.00

[HKEY_CLASSES_ROOT\ShellFile]

[HKEY_CLASSES_ROOT\ShellFile\Shell]

[HKEY_CLASSES_ROOT\ShellFile\Shell\Open]

[HKEY_CLASSES_ROOT\ShellFile\Shell\Open\Command]
@=hex(2):43,00,3a,00,5c,00,70,00,61,00,74,00,68,00,5f,00,65,00,78,00,74,00,5c,\
  00,62,00,61,00,73,00,68,00,2e,00,65,00,78,00,65,00,20,00,2d,00,63,00,20,00,\
  22,00,73,00,6f,00,75,00,72,00,63,00,65,00,20,00,24,00,30,00,3b,00,72,00,65,\
  00,61,00,64,00,22,00,20,00,25,00,31,00,20,00,25,00,2a,00,00,00

[HKEY_CLASSES_ROOT\ShellFile\ShellEx]

[HKEY_CLASSES_ROOT\ShellFile\ShellEx\DropHandler]
@="{86C86720-42A0-1069-A2E8-08002B30309D}"

The hex part actually is "C:\cygwin\bin\bash.exe -c "source $0;read" %1 %*" which gets encoded in the export.

You probably will want to remove the read after testing, so you can write scripts that just perform a task without leaving an open window. If you need this for single scripts, you can always add it add their end.

Use assoc .ext=ShellFile after importing to link any file extension you want with this functionality. The DropHandler in this example works for Windows XP and Windows 7 (probably others too) and basically means "run the command, with all dropped filenames as arguments".

Use this as a script (echotest.ext) to test basic functionality:

echo $0 $*;

Squeezy

Posted 2013-06-18T08:35:22.343

Reputation: 5 930

Perhaps you should add some sort of "tl;dr" or so pointing out that the part people will have missed is the ShellEx\DropHandler key, since people with this question will already either have the relevant file association or know how to make it. (Also, couldn't you simplify that .reg file quite a bit from the mechanically exported one? Surely there's no actual need for the hex-encoded UTF-16 formatting?) – SamB – 2016-01-07T18:21:02.560

Feel free to edit answers and questions if you have any improvements. – Squeezy – 2016-01-07T18:27:20.633

+1 for using source eliminating invocation of another shell and answering my side question about drag and drop. Unfortunately it is not the main question, so unfortunately you won't get the bounty. But thanks. I tried to figure this out without success. (Y) – Adrian – 2013-06-24T19:28:28.213

This will allow you to directly use shellscripts in the SendTo folder, instead of creating a link to bash.exe with the parameter of the script. I actually believe this answers your question, while the accepted answer provides a workaround. Not going to argue though :P – Squeezy – 2013-06-24T19:32:12.120

Oh, good to know. Thanks. Hmmm, not sure who to give the bounty to then. :( – Adrian – 2013-06-24T19:38:35.213

mpy, he solved your problem first. I just worked this out, out of curiosity. Also I can't stop using SendTo and Drag & Drop to scripts ever since, so that shall be my prize! – Squeezy – 2013-06-24T19:40:34.680

+1 also from me for source, this is really a good point. @Adrian: Now you know, why SU didn't let you award the bounty too fast. IMHO Squeezy's answer deserves the bounty, because his answer is more elegant; if you feel bad about that ;) you still can accept my answer (as it solved your problem, too), but I would also be fine with upvote only. – mpy – 2013-06-24T20:28:31.587

It's so annoying how windows requires that the Unicode text has to be put in via hex(2). :( What method do you use to encode your Unicode text? – Adrian – 2013-06-28T08:09:46.913

@Squeezy, is there a way of adding this to the Open with submenu? That way I could add an 'bash debug' version. – Adrian – 2013-06-28T16:12:51.480

@Squeezy, it turns out that open command could be added using the command ftype ShellFile=c:\cygwin\bin\bash -c "source \"$0\"; read" "%1" %* which is less error prone. Also note the escaped and non-escaped quotes which are required for ensuring that this will work with file names with spaces in them. – Adrian – 2013-06-28T16:53:48.103

Actually the command should be ftype ShellFile=c:\cygwin\bin\bash -c "source \"$(/bin/cygpath $(/bin/cygpath -wl \"$0\")\")\"; read" "%1" %* as this will keep the warning message stating that $0 is a MS-DOS style path unless environment variable CYGWIN is assigned the value nodosfilewarning in the System variable. – Adrian – 2013-06-29T06:36:59.403

Yes, you can add the open command through ftype (which I actually did). But the DropHandler will need registry magic anyway, so I just posted the full export here. Open with should be rather easy, just add a handler to the files and link it with the command you want to run. Alternatively you can add a second command handler and name it Debug rightaway :) – Squeezy – 2013-06-29T15:05:04.587

4

Here is how to pass an argument to a bash shell function via SendTo (or via drag & drop). As an example I used the builtin echo. Set the target for your link in the SendTo folder as follows:

C:\cygwin\bin\bash.exe -c "echo Argument: $0; read"

Here $0 stands for the first argument after the given command linea), i.e. the full filename of the file on which the sendto action was executed. read keeps the window open, so that you can read the message. (I tested this with cygwin's bash, but I think mingw's bash should work, too.)

In your case, the target should be

c:\MinGW\msys\1.0\bin\bash.exe -c "/path/to/your/script.sh $0; read"

Now your script can process the filename. But note, that the filename is passed to the script as the first argument, so inside the script the filename is referenced as $1.


Last, but not least here are two screenshots as a summary:

enter image description here


enter image description here


a) You quoted man bash:

-c string If the -c option is present, then commands are read from string. If there are arguments after the string, they are assigned to the positional parameters, starting with $0.

To understand that, use e.g. the following target line:

C:\cygwin\bin\bash.exe -c "echo This is $0; read" Foo Bar Baz

This will print This is Foo, while

C:\cygwin\bin\bash.exe -c "echo This is $2; read" Foo Bar Baz

will print This is Baz. So the "string" is everything between the apostrophes, and Foo Bar Baz are the arguments.

mpy

Posted 2013-06-18T08:35:22.343

Reputation: 20 866

1Ahhh, that's what that meant. Makes sense now. Thank you. I'll award you the bounty as soon as SO will let me. (says that I can do it in 11 hours for some reason shrug) – Adrian – 2013-06-24T17:54:11.110

0

If Windows refuses to link to a .sh file, you could maybe try using a .bat file that invokes the .sh script.

If that doesn't work, you could also try to compile the .bat into .exe.
A quick google found :

Batch Compiler
Bat-To-Exe

harrymc

Posted 2013-06-18T08:35:22.343

Reputation: 306 093

I know that I can use a proxy bat or exe. I would like to know if it can be done without such a proxy. – Adrian – 2013-06-24T17:28:16.150

0

Try this updated version of the REG file (note I use 64-bit Windows 7; use System32 instead of SysWOW64 if you have 32-bit Win7, Vista, or XP):

Windows Registry Editor Version 5.00

[HKEY_CLASSES_ROOT\ShellFile]
@="Shell Script"

[HKEY_CLASSES_ROOT\ShellFile\DefaultIcon]
@="C:Windows\\SysWOW64\\imageres.dll,-68"

[HKEY_CLASSES_ROOT\ShellFile\shell]

[HKEY_CLASSES_ROOT\ShellFile\shell\edit]

[HKEY_CLASSES_ROOT\ShellFile\shell\edit\command]
@="C:\\Windows\\SysWOW64\\NOTEPAD.EXE %1"

[HKEY_CLASSES_ROOT\ShellFile\shell\open]
"EditFlags"=hex:00,00,00,00

[HKEY_CLASSES_ROOT\ShellFile\shell\open\command]
@="C:\\MinGW\\msys\\1.0\\bin\\bash.exe -c \"source $0;\" \"%1 %*\""

[HKEY_CLASSES_ROOT\ShellFile\shell\print]

[HKEY_CLASSES_ROOT\ShellFile\shell\print\command]
@="C:\\Windows\\SysWOW64\\NOTEPAD.EXE /p %1"

[HKEY_CLASSES_ROOT\ShellFile\shell\runas]
"HasLUAShield"=""

[HKEY_CLASSES_ROOT\ShellFile\shell\runas\command]
@="C:\\MinGW\\msys\\1.0\\bin\\bash.exe -c \"source $0;\" \"%1 %*\""

[HKEY_CLASSES_ROOT\ShellFile\shell\runasuser]
@="@shell32.dll,-50944"
"Extended"=""
"SuppressionPolicyEx"="{F211AA05-D4DF-4370-A2A0-9F19C09756A7}"

[HKEY_CLASSES_ROOT\ShellFile\shell\runasuser\command]
"DelegatExecute"="{ea72d00e-4960-42fa-ba92-7792a7944c1d}"

[HKEY_CLASSES_ROOT\ShellFile\ShellEx]

[HKEY_CLASSES_ROOT\ShellFile\ShellEx\DropHandler]
@="{86C86720-42A0-1069-A2E8-08002B30309D}"

This will allow your shell scripts to be also run as Administrator just as any .bat file does.  In other words, it makes all shell scripts UAC compatible when using Windows Vista and Windows 7 or 8.

kramlat

Posted 2013-06-18T08:35:22.343

Reputation: 21