DotSlash on Windows
DotSlash itself works great on Windows, but comes with some caveats due to inherent Windows behaviors that might surprise Unix users.
Shebangs
Typically on Unix, DotSlash files are run by calling them directly. This relies
on them having an exec bit (i.e. chmod +x
) and letting the operating system
delegate to dotslash
through the file's
shebang
(i.e.#!/usr/bin/env dotslash
). On Windows, this doesn't work because Windows
does not use shebangs, and it relies on the file extension to determine
executability.
There are different ways of dealing with this limitation.
Explicit Interpreter
The dotslash
interpreter can be called directly with the DotSlash file as the
first argument:
C:\> dotslash path\to\dotslash_file
This method works on both Windows and Unix. The drawback (besides being verbose) is that if the DotSlash file switches to being anything other than a DotSlash file, then references will have to updated.
Sibling Batch Script
Create a file with the same name as the DotSlash file, but with an additional
.bat
(or .cmd
) extension in the same directory as the DotSlash file. Here is
an example node.bat
file that would accompany the node
DotSlash file:
@dotslash.exe "%~dpn0" %*
- The
@
suppresses echoing the command. - The
"%~dpn0"
expression corresponds to thenode
DotSlash file.cmd.exe
expands%~dpn0
to the script's Drive with the Path that contains it plus the file Name (get it?D
P
N
, see https://stackoverflow.com/a/5034119).
- The
%*
forwards the arguments passed to the batch script.
With this method you have two files:
C:\> type path\to\node
#!/usr/bin/env dotslash
{
"name": "node-v18.16.0",
"platforms": {
<<< snip >>>
C:\> type path\to\node.bat
@dotslash.exe "%~dpn0" %*
The drawbacks with this method are all the same ones associated with batch scripts and batch script resolution. The nuances of this are outside the scope of this documentation.
DotSlash Windows Shim
This is the preferred method. The DotSlash Windows Shim is a tiny .exe
executable that is placed next to the DotSlash file that performs the same
function as the batch script above, but is a native
executable rather than a batch script. This is the ideal method that allows
for easy execution without any of the drawbacks of batch scripts. But this
method requires compiling a small executable and keeping it next to the DotSlash
file.
The DotSlash Windows Shim will be made available to the public shortly under
the windows_shim
in the
DotSlash GitHub repository.
MAX_PATH
limits
DotSlash stores fetched artifacts in a cache directory and they're executed from there. DotSlash tries hard to keep the cache directory path as short as possible, but in rare cases this might not be enough.
Keeping with the node
example from above, for the common case, the cache
location of node.exe
would follow a pattern like:
C:\Users\[USERNAME]\AppData\Local\dotslash\[SHARD]\[HASH]\bin\node.exe
Where [SHARD]
is two characters and [HASH]
is 38 characters.
Again, for the common case, where you also have an 8 character username, the
node.exe
path length is roughly 99 characters. In this case, this is below the
typical 260 character
MAX_PATH
limit. However, it's possible for something like a node_modules
directory to
reach much larger depths, in which case, the underlying tool must be aware and
be able to handle this.
A possible workaround is to set the DOTSLASH_CACHE
environment variable to a
shallower directory.
argv[0]
On Unix, argv[0]
is set to the DotSlash file path. On Windows that's not
possible, so argv[0]
is the executable in the cache directory.
Long-lived dotslash.exe
processes
On Unix, DotSlash uses execv
to replace
the dotslash
process with the underlying tool being delegated to from the
cache. On Windows there's no equivalent API, so DotSlash executes the tool but
waits for it to exit before exiting itself. This means that while a tool is
running, there will also be a dotslash.exe
running. The overhead is minimal
but this presents a challenge when trying to update DotSlash itself.
On Windows, you can't remove a program that is running. So to update
dotslash.exe
you have to terminate all existing dotslash.exe
processes. This
can often be done by running taskkill /f /im dotslash.exe
.
UNC and Cygwin paths
DotSlash itself is UNC path aware but the underlying tool might not be. DotSlash tries hard to avoid UNC paths to ensure maximum compatibility.
DotSlash is not
Cygwin path aware.
Normally translation of a Cygwin path to a Windows path (i.e.
/cygdrive/c/path/to/file
to C:\path\to\file
) is handled by the Cygwin shell
executing DotSlash. But through layers of indirection it's possible to lose
this. In this case, DotSlash does not attempt to convert the path at all.