6

How can I associate all .sh files to new BASH included in Windows 10 Anniversary update?

I have tried associating .sh file using default system prompt to C:\Windows\System32\bash.exe but it just flashes console window with no result.

  • It may be that the program is running and then the console window is disappearing when it's run. Try running the .sh files from the console. – TheInitializer Aug 7 '16 at 14:38
  • I'd like to point out WSL Script application i made for the purpose. It lets you register a filetype that can then be launched from the explorer. Drag & Drop of file arguments to the associated filetype is also supported. – Joe Oct 3 at 16:50
4

The problem is that BASH uses Unix-like paths and Windows gives DOS paths. So you need to redirect DOS path to Unix path.

My solution

It is more like hack than a real solution. USE AT YOUR OWN RISK

Write tiny C# console app to redirect paths

string[] splt = args[0].Split(':');
string exe = Environment.GetFolderPath(Environment.SpecialFolder.System) + "\\bash.exe";
string arguments = "/mnt/" + splt[0].ToLower() + splt[1].Replace('\\', '/');

using (Process process = new Process())
{
    process.StartInfo.FileName = exe;
    process.StartInfo.Arguments = arguments;

    process.Start();
    process.WaitForExit();

    return process.ExitCode;
}

And then you associate .sh files with this C# app

Dirty but works

4

It's also possible to do with just a batch file:

@echo off

REM Get the full qualified path for the first argument
SET fullpath=%~f1

REM Get the drive letter and convert it to lowercase
SET drive=%fullpath:~0,1%
FOR %%i IN ("A=a" "B=b" "C=c" "D=d" "E=e" "F=f" "G=g" "H=h" "I=i" "J=j" "K=k" "L=l" "M=m" "N=n" "O=o" "P=p" "Q=q" "R=r" "S=s" "T=t" "U=u" "V=v" "W=w" "X=x" "Y=y" "Z=z") DO CALL SET drive=%%drive:%%~i%%

REM Replace \ with /
SET relpath=%fullpath:~3%
SET relpath=%relpath:\=/%

C:\Windows\System32\bash.exe --login "/mnt/%drive%/%relpath%"

Now just use Open with... (and remember to check Always use this app to open .sh files) to associate the sh files with this batch file.

EDIT: included --login argument for bash.exe to set all the appropriate linux specific environment variables (such as $PATH)

  • 3
    +1 because the solution does not need a compiler or to mess with the register (directly), but uses well known technologies. – bracco23 Apr 11 '17 at 17:47
  • This doesn't behave exactly the same as running the script after launching WSL since the PATH isn't set by bashrc. To get the right PATH change the last line to C:\Windows\System32\bash.exe -ic "/mnt/%drive%/%relpath%". – user2561747 Sep 8 '17 at 19:27
  • I think you would still need to use the registry if you wanted to skip the manual Open with dialog. – user2561747 Sep 8 '17 at 19:29
  • To set the $PATH (and other WSL environment variables) correctly, you just need to use bash.exe --login [script] instead of just `bash.exe [script]". And the .cmd file can be assigned as default program if you Right-click a .sh file -> Properties -> General tab -> Type Of File -> Change, then click Browse and find the .cmd I'm gonna edit the answer to include that! – Leonel Oct 15 '17 at 15:39
  • When starting that batch from a 32bit application, bash.exe is not found. Explanation & Workaround: github.com/Microsoft/BashOnWindows/issues/… – casper Oct 16 '17 at 0:04
2

The equivalent Vbscript method (for PSSGCSim's C# code) would be:

If WScript.arguments.count <> 0 And LCase(Right(WScript.Arguments(0), 3)) = ".sh" Then
    Dim WshShell: Set WshShell = WScript.CreateObject("Wscript.Shell")
    strSHfile = WScript.Arguments(0)
    MyArr = Split(strSHfile, ":")
    strSHfile = "/mnt/" & LCase(MyArr(0)) & MyArr(1)
    strSHfile = Replace(strSHfile,"\","/")
    WshShell.Run "%systemroot%\system32\bash.exe " & """" & sSHfile  & """",,True
    Set WshShell = Nothing
End If

And the file association REG file is here:

Windows Registry Editor Version 5.00

[HKEY_CLASSES_ROOT\.sh]
@="shfile"

[HKEY_CLASSES_ROOT\shfile]
@="SH Script File"

[HKEY_CLASSES_ROOT\shfile\shell\open\command]
@="wscript.exe \"D:\\Scripts\\bash.vbs\" \"%1\""

To make it run .SH files from network, you need to alter the script.

1

This works fine with MinGW (I personally prefer one bundled with a SmartGit):

    ftype bashfile="C:\Program Files\SmartGit\git\bin\bash.exe" "%1" %*
    assoc .sh=bashfile

If running from the batch script '%' -> '%%':

    ftype bashfile="C:\Program Files\SmartGit\git\bin\bash.exe" "%%1" %%*
    assoc .sh=bashfile
-1

Since Windows 10 still didn't provide this feature (Nor drag-over to .sh) by default, I've decided to make a registry key that does just that;

You will be able to open an .sh file correctly after associating it to bash.exe; in addition, you can drag files to the .sh script to pass them as parameters.

You can download the key here:

http://www.mediafire.com/file/8lqd1v693uj1g6t/ShellBashScriptOpen_v7.rar

The key also enables the option to run the script in elevated mode (right click option - both windows admin and Linux superuser), while an extra (optional) key enables right click > edit with nano

Remember you have to have set bash.exe as default program to open .sh files to apply these changes (the executable path is C:/Windows/System32/bash.exe)

The main registry key executes the following script (being a reg key, remember \" becomes ", \$ becomes $, \\ becomes \ and %% becomes %):

#This makes bash.exe silently execute the command between quotes (whole code)
"%SYSTEMROOT%\System32\bash.exe" -c "

#Parses the dragged file paths from Windows paths to unix paths
path_param=\$(echo \"%*\" | sed 's/[[:space:]]\\([A-Z]:\\)/\\n\\1/g' | sed 's/[A-Z]:/\\/mnt\\/\\L&/g' | tr '\\\\' '\\/'\');
mapfile -t path_param <<< \"\$path_param\";
path_param=(\"\${path_param[@]//:}\");

#Same, but with the .sh script path
path_exec=\$(echo \"%l\" | sed 's/[[:space:]]\\([A-Z]:\\)/\\n\\1/g' | sed 's/[A-Z]:/\\/mnt\\/\\L&/g' | tr '\\\\' '\\/'\');
path_exec=\"\${path_exec//:}\";

#Removes the wole path (leaving only the file name) if the parameters are in the same directory of the script
if [[ \"\${path_param%%\\/*}\" -ef \"\${path_exec%%\\/*}\" ]];
    then path_param=(\"\${path_param[@]/#\${path_param%%\\/*}\\/}\");
fi;

#Sets working directory to the folder where the script is located
cd \"\${path_exec%%\\/*}\";

#Executes script with or without parameters
if [[ \$path_param == \"\" ]];
    then \"\$path_exec\";
    else \"\$path_exec\" \"\${path_param[@]/#\${path_exec%%\\/*}\\/}\";
fi;

#Leaves WSL console open after the .sh script finishes executing
cd ~; bash; "

ORIGINAL POST: Can I drag and drop files to an .sh script using Bash on Ubuntu on Windows or Windows Subsystem for Linux (WSL)?

  • 1
    Please post the answer here, not just a link.  (I realize that the link in this answer points to another Super User question — but the answer there is also a link-only answer.) – Scott Nov 4 '17 at 15:31
  • @Scott I edited the answer (used the original post's answer with some changed) and added a link to the original post in the bottom – Alex Sim Nov 4 '17 at 15:44
  • This is still a link-only answer! – Scott Nov 4 '17 at 15:52
  • @Scott Edited after I got it back up (it was deleted by another moderator, along with the original post answer [which is still deleted]). Is the answer OK now or should I still make some changes? Also what about the other post? – Alex Sim Nov 4 '17 at 18:49
  • Please do not post the same answer to multiple questions. If the same information really answers both questions, then one question (usually the newer one) should be closed as a duplicate of the other. You can indicate this by voting to close it as a duplicate or, if you don't have enough reputation for that, raise a flag to indicate that it's a duplicate. Otherwise tailor your answer to this question and don't just paste the same answer in multiple places. – DavidPostill Nov 4 '17 at 20:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.