I would like to identify when Emacs is running on WSL (Windows Subsystem for Linux).
Normally I use system-type variable to check if Emacs is on Linux, Windows or MacOS X.
Though in this case it returns gnu/linux:

system-type is a variable defined in ‘C source code’.
Its value is ‘gnu/linux’

The value is a symbol indicating the type of operating system you are using.
Special values:
  ‘gnu’          compiled for a GNU Hurd system.
  ‘gnu/linux’    compiled for a GNU/Linux system.
  ‘gnu/kfreebsd’ compiled for a GNU system with a FreeBSD kernel.
  ‘darwin’       compiled for Darwin (GNU-Darwin, macOS, ...).
  ‘ms-dos’       compiled as an MS-DOS application.
  ‘windows-nt’   compiled as a native W32 application.
  ‘cygwin’       compiled using the Cygwin library.
Anything else (in Emacs 26, the possibilities are: aix, berkeley-unix,
hpux, usg-unix-v) indicates some sort of Unix system.

Which is what it is expected, though...
I want to add a specific check to use the Windows native browser, not the one on WSL.
I currently do that setting:

(setq browse-url-browser-function 'my-browse-url-function)

But I only want to do this in WSL, not in real Linux.
Is there a way to do it?


I would check for an environment variable using getenv. You may want to check what variables are available in your typical WSL shell, but one option would be to check for a Windows-specific PATH entry, perhaps:

(string-match-p "Windows" (getenv "PATH"))

You could also do (string-match-p "Microsoft" (shell-command-to-string "uname -a"))

Likely in your my-browse-url-function you're probably depending on a Windows specific path to exist. You could just check that it exists and is executable with file-executable-p like the following code does. However, this may not be enough if you dual boot and mount the windows C: drive to the same mount point.

;; setup browser function when running in WSL
(defconst powershell-exe "/mnt/c/Windows/System32/WindowsPowerShell/v1.0/powershell.exe")

(when (file-executable-p powershell-exe)
  (defun my\wsl-browse-url (url &optional _new-window)
    "Opens link via powershell.exe"
    (interactive (browse-url-interactive-arg "URL: "))
    (let ((quotedUrl (format "start '%s'" url)))
      (apply 'call-process powershell-exe
             nil 0 nil (list "-Command" quotedUrl))))

  (setq-default browse-url-browser-function 'my\wsl-browse-url))

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.