X410 – run WSL gui applications as native Windows applications

Software developers who work on Windows have likely heard of WSL, which stands for the Windows Subsystem for Windows. Essentially, it is a way to run Linux distributions within Windows somewhat like running a virtual machine (VM) but more seamless – or akin to running a Docker container. WSL provides support for GUI applications out-of-the-box with WSLg. The important thing to note about WSLg is that it is implemented using the RDP protocol, so GUI applications are essentially run via an RDP process running on the host Windows machine. Due to this implementation, the performance of GUI applications running on WSLg will not perform as well as would a native Windows application or compared to running the application on a regular Linux installation.

There are some really cool uses of WSL even outside of software development that may be useful for users who are somewhat technical. Some of these are from the interoperability provided with WSL:

  • Windows drive C:\ is mounted in WSL at /mnt/c
  • WSL filesystems can be accessed at \\wsl.localhost and can be mounted to network drives (for example I have \\wsl.localhost\Arch mounted as L:\)

Windows provides the ability to mount network drives using FTP or SMB – however, it doesn’t provide support natively for mounting network locations using SSH/SFTP. Linux has a FUSE filesystem called sshfs. With WSL, this means network locations can be mounted and accessed from Windows. Similarly, Windows does not natively support mounting external drives containing ext4 formatted partitions.

X410 is a really cool alternative to WSLg, which allows X-Window GUI apps to run like any other Windows application. Note that X410 does require the purchase of a license. The license I purchased is for perpetual for the version when I purchased, though updating to newer versions of X410 will require an additional purchase. Here is an example of Caja running in X410: Caja File Manager in X410

Notice how the Window appears like a normal Windows application would. For comparison, here is what Caja looks like in WSLg: Caja File Manager in WSLg

While it may not look like much of a difference, the advantage of X410 is not about the appearance but performance. The UI responsiveness running X410 is noticeably better than running in WSLg.

Sysinternals Suite for Windows: a collection of CLI and GUI system utilities

Sysinternals Suite is a set of command-line and GUI tools for Windows.

Sysinternals Suite - Process Monitor UI

The default download (for x64/x86 CPUs) contains both 64- and 32-bit binaries. If you are using a 64-bit machine, you can run the following PowerShell script in your directory of the extracted zip files to have the default .exe file be a symlink to the 64-bit version rather than the 32-bit executable:

$files = (ls)
$x64s = @{}
$x86s = @{}
$x64sTox86s = @{}

for ($i = 0; $i -lt $files.Length; $i++) {
    $filename = $files[$i].Name
    if ($filename.EndsWith("64.exe")) {
        $x64s[$filename] = $true
    } elseif ($filename.EndsWith(".exe")) {
        $x86s[$filename] = $true
    }
}

foreach ($x64 in $x64s.Keys) {
    $x86 = $x64.Replace("64.exe", ".exe")
    if ($x86s.ContainsKey($x86)) {
        $x64sTox86s[$x64] = $x86
    }
}

foreach ($x64 in $x64sTox86s.Keys) {
    $x86 = $x64sTox86s[$x64]
    Remove-Item -Path $x64
    New-Item -Type SymbolicLink -Path $x64 -Target $x86
}Code language: PHP (php)

change Visual Studio Code application font

Changing the application font (not the text editor font, which can already be changed in settings) in Visual Studio Code can be done via an extension called Custom CSS and JS Loader. After installing the extension, edit/add the following line to settings.json:

"vscode_custom_css.imports": ["file:///C:/Users/nickcummins/Documents/VSCode-Custom.css"],

replacing nickcummins with your username. Then, create this VSCode-Custom.css on your filesystem containing the following:

.windows,
.monaco-workbench.windows {
    font-family: Arial;
}

.monaco-workbench .part > .content {
	font-size: 0.9em;
}

replacing Arial with the preferred font. Finally, re-open VS Code running as Administrator. Search for the command as shown in the screenshot, and click on it.

You’ll be prompted to restart VS Code. You should notice the new font being used when it re-opens. You can close the elevated instance of VS Code and re-open it as a normal user. 

Changing the default system font in Windows 11

Although Windows 11’s built-in settings provides a Personalization > Fonts section, there actually isn’t a way to change the system font from here:

Windows settings - Personalization - Fonts

This can be easily changed on many Linux distributions using GUI tools, such as the desktop environment’s settings manager. Here you can see Liberation Sans and Liberation Mono configured in the fonts tab of xfce4-settings:

Xfce4 Appearance Settings - Fonts

There is a way to change the system font in Windows, which involves 2 steps:

  1. Using this registry script, changing Arial to the desired Windows font:
    Windows Registry Editor Version 5.00
    
    [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Fonts]
    "Segoe UI (TrueType)"=""
    "Segoe UI Bold (TrueType)"=""
    "Segoe UI Bold Italic (TrueType)"=""
    "Segoe UI Italic (TrueType)"=""
    "Segoe UI Light (TrueType)"=""
    "Segoe UI Semibold (TrueType)"=""
    "Segoe UI Symbol (TrueType)"=""
    
    [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\FontSubstitutes]
    
    "Segoe UI"="Arial"
    
  2. Changing the WindowMetrics font, via one of the two means:
    • Another registry script, replacing all occurrences of the font represented in hex to the desired font in hex representation. The current font in the script is Arial (which was the default font in many earlier versions of Windows):
      Windows Registry Editor Version 5.00
      
      [HKEY_CURRENT_USER\Control Panel\Desktop\WindowMetrics]
      "IconTitleWrap"="1"
      "Shell Icon Size"="32"
      "BorderWidth"="-15"
      "CaptionFont"=hex:f4,ff,ff,ff,00,00,00,00,00,00,00,00,00,00,00,00,90,01,00,00,\
        00,00,00,01,00,00,00,00,41,00,72,00,69,00,61,00,6c,00,00,00,00,00,00,00,00,\
        00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,\
        00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
      "CaptionHeight"="-330"
      "CaptionWidth"="-330"
      "IconFont"=hex:f4,ff,ff,ff,00,00,00,00,00,00,00,00,00,00,00,00,90,01,00,00,00,\
        00,00,01,00,00,00,00,41,00,72,00,69,00,61,00,6c,00,00,00,00,00,00,00,00,00,\
        00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,\
        00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
      "MenuFont"=hex:f4,ff,ff,ff,00,00,00,00,00,00,00,00,00,00,00,00,90,01,00,00,00,\
        00,00,01,00,00,00,00,41,00,72,00,69,00,61,00,6c,00,00,00,00,00,00,00,00,00,\
        00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,\
        00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
      "MenuHeight"="-285"
      "MenuWidth"="-285"
      "MessageFont"=hex:f4,ff,ff,ff,00,00,00,00,00,00,00,00,00,00,00,00,90,01,00,00,\
        00,00,00,01,00,00,00,00,41,00,72,00,69,00,61,00,6c,00,00,00,00,00,00,00,00,\
        00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,\
        00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
      "ScrollHeight"="-255"
      "ScrollWidth"="-255"
      "SmCaptionFont"=hex:f4,ff,ff,ff,00,00,00,00,00,00,00,00,00,00,00,00,90,01,00,\
        00,00,00,00,01,00,00,00,00,41,00,72,00,69,00,61,00,6c,00,00,00,00,00,00,00,\
        00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,\
        00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
      "SmCaptionHeight"="-330"
      "SmCaptionWidth"="-330"
      "StatusFont"=hex:f4,ff,ff,ff,00,00,00,00,00,00,00,00,00,00,00,00,90,01,00,00,\
        00,00,00,01,00,00,00,00,41,00,72,00,69,00,61,00,6c,00,00,00,00,00,00,00,00,\
        00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,\
        00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
      "PaddedBorderWidth"="0"
      "AppliedDPI"=dword:00000060
      "IconSpacing"="-1125"
      "IconVerticalSpacing"="-1125"
      "MinAnimate"="0"
      
    • Using a 3rd party tool called Advanced System Font Changer. Note, that this tool requires a license for full use.

Change process’s priority in Windows

The simplest means to do this is by simply opening Task Manager in Windows and navigating to the Details pane. Right-click on a process in the list, then select Set priority from the menu.

Alternatively, similar to the Linux renice command, the priority can also be set via command-line in Windows using

wmic process where name="devenv.exe" CALL setpriority "high priority"Code language: JavaScript (javascript)

The aforementioned methods will not persist upon system restart. Permanently setting the default priority of a process can be achieved using a registry script. This file can contain as many entries as desired. In this example below, I set the default process priority of devenv.exe and sqlservr.exe to High 00000003:

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\devenv.exe]
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\devenv.exe\PerfOptions] 
"CpuPriorityClass"=dword:00000003

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\sqlservr.exe]
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\sqlservr.exe\PerfOptions] 
"CpuPriorityClass"=dword:00000003

ripgrep: grep like equivalent for Windows

While Windows provides similar capabilities out-of-the-box with PowerShell, most Linux users will undoubtedly be familiar with the grep command:

> grep --help
Usage: grep [OPTION]... PATTERNS [FILE]...
Search for PATTERNS in each FILE.
Example: grep -i 'hello world' menu.h main.c
PATTERNS can contain multiple patterns separated by newlines.

GNU grep home page: <https://www.gnu.org/software/grep/>
General help using GNU software: <https://www.gnu.org/gethelp/>

Fortunately, there is a cross-platform grep like equivalent for Windows (and MacOS/Linux) called ripgrep:

PS> ripgrep --help
ripgrep 14.1.0 (rev e50df40a19)
Andrew Gallant <jamslam@gmail.com>

ripgrep (rg) recursively searches the current directory for lines matching 
a regex pattern. 'By default, ripgrep will respect gitignore rules 
and automatically skip hidden files/directories and binary file

Use -h for short descriptions and --help for more details.

Project home page: https://github.com/BurntSushi/ripgrep

After installing to a location in your PATH, I also recommend creating a symlink so you can use simply type the command grep rather than ripgrep (this may require admin to create depending on your Windows settings):

New-Item -Type SymbolicLink -Path grep.exe -Target rg.exe

Alternatively, you can create a PowerShell alias using Set-Alias command.