Run .sh file on double click on Windows with Cygwin

You have to add a %1 parameter to get the association to work, e.g., like this (quotes are needed to work with paths having embedded blanks):

C:\cygwin64\bin\sh.exe -li  "%1"

The question was asked before in several places; these may be helpful:

  • How can I associate .sh files with Cygwin?
  • Cygwin/Windows/DOS integration: Tips and Tricks

The window will close when the script completes, though - unless you make some provision for that in the script, e.g., by following that with a read command (since the association is only passing the script as an argument). Here are a few discussions on that aspect:

  • Run a shell script in a new cygwin window
  • Re: shortcut to start xemacs in bash cygwin window
  • Run a command in another cygwin window and not exit

I was unhappy with the other answers found here and elsewhere on the Internet, so I've spent a considerable amount of time working out how to do this properly. Here's what I've come up with.

  1. Create a key named .sh and set it's (Default) value to Shell Script under HKEY_CLASSES_ROOT.
    • Create a key named Shell Script under HKEY_CLASSES_ROOT, and set the (Default) value to Shell Script.
  2. Create a key named shell under HKEY_CLASSES_ROOT\Shell Script.
  3. Create a key named open under HKEY_CLASSES_ROOT\Shell Script\shell and set the (Default) value to Run with Cygwin.
  4. Create a key named command under HKEY_CLASSES_ROOT\Shell Script\shell\open and set the (Default) value to "C:\cygwin64\bin\mintty.exe" -i /Cygwin-Terminal.ico C:\cygwin64\bin\bash.exe -l -c "cd $(dirname \"$(cygpath -u \"%1\")\") ; $(cygpath -u \"%1\") ; exec bash" (change C:\cygwin64\ to C:\cygwin\ if you're using the 32bit version).

Now you can just double click on your .sh file and it will run as you expect it to.

Bonus:

  1. Create a key named DefaultIcon under HKEY_CLASSES_ROOT\Shell Script and set the (Default) value to %SystemRoot%\System32\imageres.dll,-68. This will apply the standard Batch file icon to your shell scripts.

I've also created a registry patch file (Save as Run With Cygwin.reg):

Windows Registry Editor Version 5.00

[HKEY_CLASSES_ROOT\.sh]
@="Shell Script"

[HKEY_CLASSES_ROOT\Shell Script]
@="Shell Script"

[HKEY_CLASSES_ROOT\Shell Script\DefaultIcon]
@="%SystemRoot%\\System32\\imageres.dll,-68"

[HKEY_CLASSES_ROOT\Shell Script\shell]

[HKEY_CLASSES_ROOT\Shell Script\shell\open]
@="Run with Cygwin"

[HKEY_CLASSES_ROOT\Shell Script\shell\open\command]
@="\"C:\\cygwin64\\bin\\mintty.exe\" -i /Cygwin-Terminal.ico C:\\cygwin64\\bin\\bash.exe -l -c \"cd $(dirname \\\"$(cygpath -u \\\"%1\\\")\\\") ; $(cygpath -u \\\"%1\\\") ; exec bash\""

Put the following in a batch file, and select it for "Opens with" for ".sh" files:

@echo off
C:\cygwin\bin\bash.exe -lc "cd ""%cd%""; ""$(cygpath -u "%1")"""

The 'cd ""%cd%"";' part ensures that the shell script will always start in the same directory from which it was called, even if your Bash profile tries to start in your home directory. The multiple layers of double quotes are necessary to escape backslashes and allow for spaces in path names.

An alternative to the login (-l) option, for making sure non-builtin commands are available, is to add the bin directory to your path:

@echo off
set path=%path%;C:\cygwin\bin
bash -c """$(cygpath -u "%1")"""