{"id":18913744,"url":"https://github.com/archenoth/wslsetup","last_synced_at":"2026-03-19T07:05:33.773Z","repository":{"id":150483282,"uuid":"220564745","full_name":"Archenoth/WSLSetup","owner":"Archenoth","description":"How I like to set up WSL","archived":false,"fork":false,"pushed_at":"2020-02-21T01:32:30.000Z","size":93,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-06-01T05:34:30.177Z","etag":null,"topics":["org-mode-notes","wsl"],"latest_commit_sha":null,"homepage":null,"language":"AutoHotkey","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Archenoth.png","metadata":{"files":{"readme":"README.org","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-11-08T23:40:07.000Z","updated_at":"2025-05-04T05:25:20.000Z","dependencies_parsed_at":"2023-04-18T13:49:18.295Z","dependency_job_id":null,"html_url":"https://github.com/Archenoth/WSLSetup","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/Archenoth/WSLSetup","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Archenoth%2FWSLSetup","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Archenoth%2FWSLSetup/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Archenoth%2FWSLSetup/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Archenoth%2FWSLSetup/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Archenoth","download_url":"https://codeload.github.com/Archenoth/WSLSetup/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Archenoth%2FWSLSetup/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28826480,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-27T18:44:20.126Z","status":"ssl_error","status_checked_at":"2026-01-27T18:44:09.161Z","response_time":168,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["org-mode-notes","wsl"],"created_at":"2024-11-08T10:08:50.638Z","updated_at":"2026-01-27T23:07:07.193Z","avatar_url":"https://github.com/Archenoth.png","language":"AutoHotkey","funding_links":[],"categories":[],"sub_categories":[],"readme":"#+TITLE:Windows 10 WSL setup\n#+AUTHOR:Archenoth\n#+EMAIL:archenoth@gmail.com\n:SETTINGS:\n#+STARTUP: hidestars inlineimages\n#+DRAWERS: SETTINGS\n:END:\n\nWSL is nice on its own, but I've found a few ways to make it integrate with Windows a lot nicer!\nSo this is what I do when I set up WSL!\n\n* Symlinks\nThe first thing I do when I set up a new WSL instance is make a few symlinks between the two systems.\n\nThe first one is for the root drive (Requires root):\n#+begin_src sh :dir /sudo:root@localhost:/\n  ln -s /mnt/c /host\n#+end_src\n\nThen I add a few folders in my home folder that make the link between Windows and Linux pretty seamless. (If you already have these folders, you might need to move or nuke them first)\n\nIf you aren't running this from Emacs, you can hit =[Windows] + [R]=, type \"=%userprofile%=\" and hit =[Enter]=. Then hit =[Ctrl] + [L]= type \"=bash=\" and =[Enter]= again.\nThis should put you in correct folder this should be run from.\n#+begin_src sh :dir (string-trim (shell-command-to-string \"wslpath `cmd.exe /c 'echo %USERPROFILE%'`\"))\n  for i in Desktop Documents Downloads Videos Music Pictures; do\n    ln -s $i ~\n  done\n\n  mkdir ~/Documents/Code ~/Documents/Writing\n  ln -s ~/Documents/Code ~/Documents/Writing ~\n#+end_src\n\n\n* Base programs\nAfter installing [[https://chocolatey.org/][Chocolatey]], installing some essential programs can be done from the following in an /elevated/ command prompt.\n#+begin_src bat :tangle ~/Desktop/install-essentials.bat\n  choco install xming autohotkey wsltty -y\n#+end_src\n\nAnd after that's done, the wsltty terminal can be set up with the following:\n#+begin_src sh :shcmd \"cmd.exe\"\n  C:\\ProgramData\\Chocolatey\\lib\\wsltty\\tools\\wslttyinstall\\install.bat\n#+end_src\n\nMy configuration for wsltty is basically just to make it look like a simple and slightly transparent terminal:\n[[./mintty.png]]\n\nThis goes in =%APPDATA%\\wsltty\\config=\n#+begin_src conf :tangle (string-trim (shell-command-to-string \"wslpath `cmd.exe /c 'echo %APPDATA%/wsltty/config'`\"))\nThemeFile=dainty-monokai-night-mod\nTransparency=5\nOpaqueWhenFocused=no\nCursorType=block\nFont=Consolas\nFontHeight=11\nZoomShortcuts=no\nAltFnShortcuts=no\nBackgroundColour=0,0,0\n#+end_src\n\nThe above theme is follows, and goes in =%APPDATA%\\wsltty\\themes\\dainty-monokai-night-mod= (Originally from [[https://github.com/alexanderte/dainty-wsltty][here]], and modified slightly for contrast):\n#+begin_src conf :tangle (string-trim (shell-command-to-string \"wslpath `cmd.exe /c 'echo %APPDATA%/wsltty/themes/dainty-monokai-night-mod'`\"))\n# source: https://github.com/alexanderte/dainty-wsltty\n# MIT License\n\nBackgroundColour=40, 40, 40\nBlack=51, 51, 51\nBlue=106, 126, 200\nBoldBlack=102, 102, 102\nBoldBlue=129, 154, 255\nBoldCyan=102, 217, 239\nBoldGreen=166, 226, 46\nBoldMagenta=195, 159, 255\nBoldRed=249, 38, 114\nBoldWhite=248, 248, 242\nBoldYellow=226, 226, 46\nCursorColour=248, 248, 240\nCyan=86, 173, 188\nForegroundColour=222, 222, 222\nGreen=134, 180, 43\nMagenta=195, 159, 255\nRed=196, 38, 94\nWhite=227, 227, 221\nYellow=179, 180, 43\n#+end_src\n\nFor XMing, I update my [[~/.Xresources][.Xresources]] file to get a slightly nicer looking X11:\n#+begin_src conf :tangle ~/.Xresources\n  Xft.antialias: 1\n  Xft.dpi: 96\n  Xft.hinting: 1\n  Xft.hintstyle: hintsfull\n  Xft.lcdfilter: lcddefault\n  Xft.rgba: rgb\n#+end_src\n\nThen I edit my [[~/.profile]] to include things like the following at the end:\n#+begin_src sh\n  # Allow graphical Linux programs to know how to connect to XMing\n  export DISPLAY=127.0.0.1:0\n\n  # Make XMing look nicer\n  xrdb -merge $HOME/.Xresources\n#+end_src\n\nFor AutoHotKey, I make a little script to start wsltty when I hit =Ctrl + Alt + T=, just like the default keybinding in a lot of Linux window managers.\n#+begin_src ahk :tangle ~/Code/ahk/terminal.ahk\n  ^!t::\n      Run, C:\\Users\\Archenoth\\AppData\\Local\\wsltty\\bin\\mintty.exe --WSL= --configdir=\"%APPDATA%\\wsltty\" -~\n  Return\n#+end_src\n\nI also make a little vbscript file to run XMing, and then to start bash once (to run my .profile with the Linux-side XMing configuration):\n#+begin_src vbscript :tangle ~/Code/vbs/start-xming-profile.vbs\n  CreateObject(\"Wscript.Shell\").Run \"\"\"C:\\Program Files (x86)\\Xming\\Xming.exe\"\" :0 -clipboard -multiwindow\", 0, False\n  CreateObject(\"Wscript.Shell\").Run \"bash -lic exit\", 0, True\n#+end_src\n\nAfter making these, I copy shortcuts for that *last two* scripts above into my =shell:startup= folder. (You can access by typing that into the run dialog you get by hitting =Win + R=)\n\nThat will make this stuff all start on login, and without popping up any ugly command windows on startup. (That's why I used vbscript here--to squelch the command prompt popups)\n\n* Startup services\nTo get Linux *services* starting on Windows start (Before anyone logs in), I create a startup script in /etc/ named after the user that will run it, so in my case, I call it =rc.arch.local=:\n#+begin_src sh :tangle /sudo:root@localhost:/etc/rc.arch.local :tangle-mode (identity #o500)\n  #!/bin/bash\n  service cron start\n  service ssh start\n#+end_src\n\nI then add my user to a sudoers files to allow this to be run as root without a password:\n#+begin_src sh :tangle /sudo:root@localhost:/etc/sudoers.d/archrc :tangle-mode (identity #o400)\n  # Startup script access for default user\n  archenoth ALL=(root) NOPASSWD: /etc/rc.arch.local\n#+end_src\n\nIn Windows, I open up the Task Scheduler and make scheduled tasks to run the [[/sudo:root@localhost:/etc/rc.arch.local][/etc/rc.arch.local]] file with passwordless sudo when the computer starts.\n\nThis is what the task I made looks like exported as XML (You may need to change the user in here if you are planning on importing it into your Task Scheduler):\n#+begin_src xml :tangle ~/Desktop/WSL rc.arch.local.xml\n  \u003c?xml version=\"1.0\" encoding=\"UTF-16\"?\u003e\n  \u003cTask version=\"1.2\" xmlns=\"http://schemas.microsoft.com/windows/2004/02/mit/task\"\u003e\n    \u003cRegistrationInfo\u003e\n      \u003cDate\u003e2019-11-08T12:49:06.8481246\u003c/Date\u003e\n      \u003cAuthor\u003eJIRACHI\\Archenoth\u003c/Author\u003e\n      \u003cDescription\u003eStarts the Linux Subsystem rc.arch.local script\u003c/Description\u003e\n      \u003cURI\u003e\\WSL rc.arch.local\u003c/URI\u003e\n    \u003c/RegistrationInfo\u003e\n    \u003cTriggers\u003e\n      \u003cBootTrigger\u003e\n        \u003cEnabled\u003etrue\u003c/Enabled\u003e\n      \u003c/BootTrigger\u003e\n    \u003c/Triggers\u003e\n    \u003cPrincipals\u003e\n      \u003cPrincipal id=\"Author\"\u003e\n        \u003cUserId\u003eS-1-5-21-3695860422-1816032588-548272057-1001\u003c/UserId\u003e\n        \u003cLogonType\u003eS4U\u003c/LogonType\u003e\n        \u003cRunLevel\u003eLeastPrivilege\u003c/RunLevel\u003e\n      \u003c/Principal\u003e\n    \u003c/Principals\u003e\n    \u003cSettings\u003e\n      \u003cMultipleInstancesPolicy\u003eIgnoreNew\u003c/MultipleInstancesPolicy\u003e\n      \u003cDisallowStartIfOnBatteries\u003efalse\u003c/DisallowStartIfOnBatteries\u003e\n      \u003cStopIfGoingOnBatteries\u003etrue\u003c/StopIfGoingOnBatteries\u003e\n      \u003cAllowHardTerminate\u003etrue\u003c/AllowHardTerminate\u003e\n      \u003cStartWhenAvailable\u003etrue\u003c/StartWhenAvailable\u003e\n      \u003cRunOnlyIfNetworkAvailable\u003efalse\u003c/RunOnlyIfNetworkAvailable\u003e\n      \u003cIdleSettings\u003e\n        \u003cStopOnIdleEnd\u003etrue\u003c/StopOnIdleEnd\u003e\n        \u003cRestartOnIdle\u003efalse\u003c/RestartOnIdle\u003e\n      \u003c/IdleSettings\u003e\n      \u003cAllowStartOnDemand\u003etrue\u003c/AllowStartOnDemand\u003e\n      \u003cEnabled\u003etrue\u003c/Enabled\u003e\n      \u003cHidden\u003efalse\u003c/Hidden\u003e\n      \u003cRunOnlyIfIdle\u003efalse\u003c/RunOnlyIfIdle\u003e\n      \u003cWakeToRun\u003efalse\u003c/WakeToRun\u003e\n      \u003cExecutionTimeLimit\u003ePT72H\u003c/ExecutionTimeLimit\u003e\n      \u003cPriority\u003e7\u003c/Priority\u003e\n    \u003c/Settings\u003e\n    \u003cActions Context=\"Author\"\u003e\n      \u003cExec\u003e\n        \u003cCommand\u003eC:\\Windows\\System32\\bash.exe\u003c/Command\u003e\n        \u003cArguments\u003e-c \"sudo /etc/rc.arch.local\"\u003c/Arguments\u003e\n      \u003c/Exec\u003e\n    \u003c/Actions\u003e\n  \u003c/Task\u003e\n#+end_src\n\nI didn't bother with vbscript for this one since it runs before I even log on, so there still aren't any command prompt popups.\n\nAnd that about covers the main tweaks I make! Feel free to steal as many of these ideas as you like..! ^^\n\n* Tweaks\nThese aren't as major, but they are nice little things I sometimes enjoy being able to use.\n\n** Using Linux programs from cmd.exe\nI wrote a little Windows binary that, if you rename it to a Linux command, that Linux command will run. So if you like having git.exe on your path, you can use the Linux version with your Linux SSH config.\n\nTo set it up, you can run the following:\n#+begin_src sh\n  mkdir -p /host/Oshawott/bin\n  wget https://github.com/Archenoth/wsl_proxy/releases/download/0.2.0/wsl_proxy.exe -O /host/Oshawott/wsl_proxy.exe\n\n  remaining=1023\n  find /bin /usr/bin /usr/local/bin /usr/sbin -executable -type f -maxdepth 1 ! -name bash -printf \"%f\\n\" \\\n      | sort | uniq | while read bin; do\n      echo \"Linking $bin\"\n      if [ \"$remaining\" -le \"0\" ]; then\n          remaining=1023\n          cp /host/Oshawott/wsl_proxy.exe /host/Oshawott/wsl_proxy2.exe\n          mv /host/Oshawott/wsl_proxy.exe \"/host/Oshawott/bin/$bin.exe\"\n          mv /host/Oshawott/wsl_proxy2.exe /host/Oshawott/wsl_proxy.exe\n      else\n          remaining=$((remaining-1))\n          ln /host/Oshawott/wsl_proxy.exe \"/host/Oshawott/bin/$bin.exe\"\n      fi\n  done\n#+end_src\n\nThis will download the =wsl_proxy.exe= program, and link every executable in a number of bin folders likely on your =$PATH=. (We aren't gonna use =$PATH= proper since it will return many executables that aren't actually if you have any Windows paths in there)\n\nThe 1023 links per copy business is because each file can have only a maximum of 1024 links at any given time. (And yes, WSL hardlinks work on Windows)\n\nTo use this, you'll need to change your \"Path\" in =sysdm.cpl= under \"Advanced\" -\u003e \"Environment Variables\" -\u003e \"User variables for \u003cyou\u003e\" to include =C:\\Oshawott\\bin=.\n\n** Run exes without writing \".exe\"\nYou can use =command_not_found_handle= to automatically append =.exe= to your commands if they don't exist on Linux and try again.\nAll you need to do is modify the handle in [[/sudo:root@localhost:/etc/bash.bashrc::command_not_found_handle][bash.bashrc]] to look like:\n\n#+begin_src sh\n  if [ -x /usr/lib/command-not-found -o -x /usr/share/command-not-found/command-not-found ]; then\n      function command_not_found_handle {\n          if which \"$1.exe\" 1\u003e/dev/null 2\u003e\u00261; then\n              EXE=\"$1.exe\"\n              shift\n              $EXE $*\n              return $?\n          else\n              # check because c-n-f could've been removed in the meantime\n              if [ -x /usr/lib/command-not-found ]; then\n                  /usr/lib/command-not-found -- \"$1\"\n                  return $?\n              elif [ -x /usr/share/command-not-found/command-not-found ]; then\n                  /usr/share/command-not-found/command-not-found -- \"$1\"\n                  return $?\n              else\n                  printf \"%s: command not found\\n\" \"$1\" \u003e\u00262\n                  return 127\n              fi\n          fi\n      }\n  fi\n#+end_src\n\nSince WSL does pathname translation, this means you can do crazy things like =explorer Code/ahk= and it will open that code folder with =explorer.exe= properly if it's in your $PATH!\n\n*Note:* Programs run this way won't work on paths that only WSL can see. Which is another good reason to have [[Symlinks][symlinks between your two systems set up]]!\n\n** Turn off dings every time you hit tab (And other things)\nI don't really like how tab completion, or many other actions in Linux make my computer ding at me, so I like to replace the =bell-style= in [[/sudo:root@localhost:/etc/inputrc::bell-style][/etc/inputrc]] to be =set bell-style none=.\n\n* Conclusion\nI mostly wrote this file for myself, but if you stumbled across it somehow, I hope you found these tricks useful!\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Farchenoth%2Fwslsetup","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Farchenoth%2Fwslsetup","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Farchenoth%2Fwslsetup/lists"}