Putting Together An Ubuntu Theme For Windows Terminal

Windows Terminal has proven to be one of my favorite additions to the PC world in a while. Coming from the Linux and Mac paradigm for the last decade-and-a-half, I felt like I needed a capable terminal emulator if I was going to be running a Windows machine as a daily driver again. Of course, the Windows Subsystem for Linux (WSL) just makes me giggle with glee at being able to run Ubuntu at the hypervisor-level instead of using virtualization software like VMware to do the handful of specialized tasks that I would easily perform in a Mac/Linux terminal window.

Of course, if you’re going to have a modern terminal emulator, you need to be able to customize it. Under MacOS, I was rocking a classic green-on-black look that reminded me of playing Zork on an Apple II and was great for getting that “digging around under the hood” vibe. I’ll probably bring that look back for one of my specialized terminal implementations (maybe the dedicated Telnet profile I’ve set up for dialing into the occasional BBS), but for the Ubuntu profile, I wanted something that evoked the orange and purple color scheme that I’ve come to associate with my distro of choice. These colors aren’t exactly the official “on brand” colors that Canonical uses, but they get the idea across.

In Windows Terminal, you can access settings.json from the Settings tab and add the following data to the schemes section:

{
            "background": "#3C0315",
            "black": "#282A2E",
            "blue": "#0170C5",
            "brightBlack": "#676E7A",
            "brightBlue": "#80C8FF",
            "brightCyan": "#8ABEB7",
            "brightGreen": "#B5D680",
            "brightPurple": "#AC79BB",
            "brightRed": "#BD6D85",
            "brightWhite": "#FFFFFD",
            "brightYellow": "#FFFD76",
            "cursorColor": "#FFFFFF",
            "cyan": "#3F8D83",
            "foreground": "#FFFFFD",
            "green": "#76AB23",
            "name": "Ubuntu",
            "purple": "#7D498F",
            "red": "#BD0940",
            "selectionBackground": "#FFFFFF",
            "white": "#FFFFFD",
            "yellow": "#E0DE48"
}

Once you get this inserted, you should be able to select “Ubuntu” from the Color Scheme drop-down under the Appearance tab in your Ubuntu profile, and you’ll get a terminal that looks like this:

Ubuntu color scheme in Windows Terminal

Now that we’ve got the colors all set, we just need to add a custom icon to complete the look. I just grabbed a transparent *.png of the Ubuntu logo and converted it to an *.ico file. I’m weird in that I don’t really use my library folders the way they’re intended. I keep photos on my server, so I don’t have much use for the Pictures library folder. As such, I use the folder for “system” images like custom icons, profile images, and wallpapers. I just dropped the icon into the folder and pointed my Windows Terminal profile to it. Now I’ve got a terminal implementation that reminds me that I’m running a separate operating system on top of Windows and isn’t just another basic grey/white-on-black (that look is reserved for CMD and DOSBox).

How To Remove Library Folders From This PC In Windows 10/11

I’m one of those weird people that doesn’t really use the standard library folders that come in Windows (or MacOS, for that matter), but while I can easily customize Mac’s Finder menu to not list the libraries I don’t use, customizing the Windows Explorer menu is less straightforward. I like opening new instances of Explorer to the Quick Access view where I have all my attached drives, commonly used libraries (Downloads, Desktop, and Documents), and mapped network drives available at a glance. I also have locations for files synced across my devices and the Recycle Bin pinned to the menu, giving me ahem quick access to these commonly-used locations. Because of this setup, the stock “This PC” listing is redundant–listing many of the same locations twice and taking up precious screen real estate. As such, I wanted to customize this menu as much as possible with the hope of getting it similar to my Mac’s Finder sidebar menu.

Editing the Registry

The Windows Registry holds all the power under the hood in the Windows ecosystem. The problem is that it isn’t always clear what registry key values affect what parts of the OS. Fortunately, a little Google Fu is all that is needed to find the appropriate changes to make. First, open the Registry Editor by launching regedit from the Run (WIN+R) dialog. In the Registry Editor, navigate to HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\FolderDescriptions then locate the appropriate folder according to the GUID key list below and expand the folder to show its nested PropertyBag folder.

  • Desktop: {B4BFCC3A-DB2C-424C-B029-7FE99A87C641}
  • Documents: {f42ee2d3-909f-4907-8871-4c22fc0bf756}
  • Downloads: {7d83ee9b-2244-4e70-b1f5-5393042af1e4}
  • Music: {a0c69a99-21c8-4671-8703-7934162fcf1d}
  • Pictures: {0ddd015d-b06c-45d5-8c4c-f59713854639}
  • Videos: {35286a68-3c57-41a1-bbb1-0eae73d76c95}

With the appropriate PropertyBag selected, right-click the ThisPCPolicy value in the main pane and select Modify. Change the value from Show to Hide, then click OK. Conversely, to re-show a particular folder, just change the data back to Show.

In some cases, ThisPCPolicy doesn’t have a defined value in the PropertyBag. In these cases, right-click on the main pane and select New > String Value, naming it ThisPCPolicy. Then set the value appropriately.

Enabling The Libraries Folder

For convenience sake, I do like to have access to the Libraries–just not at the top of the list. You can enable the Libraries folder in the sidebar menu through Folder Options in Windows Explorer. The check box is located under the “Navigation Pane” header below the View tab.

Putting things together like this makes Windows Explorer rather usable at this point!

How To Run Old Windows Games on Windows 11

As much as I love to dig out one of my vintage laptops to get theĀ full nostalgic retro gaming experience, sometimes it just isn’t very practical to fire up Windows 95 for a quick round of JezzBall. Unfortunately, the newer versions of Windows built on 32 and 64-bit architectures won’t run these old software relics. However, unlike Apple, Microsoft actually values backwards-compatibility. (Of course, this is mostly by necessity considering how many enterprises are running legacy software as well as due to the support of independent developers regularly bending the OS to their will, instead of the other way around.)

Windows Entertainment PackVirtue signalling aside, as part of my recent two-foot leap back into the daily-driver Windows world, I wanted to revisit one of my favorite casual diversions of the 16-bit era: Microsoft Entertainment Pack.

The only problem, of course, is that Entertainment Pack is a 16-bit application and Windows 11 won’t run 16-bit applications out of the box. Enter otvdm (forked from winevdm). Based on Wine, otvdm is a compatibility layer that adds the ability to run 16-bit Windows binaries in 64-bit exclusive versions of Windows much like the new Windows subsystems for Linux and Android. (At this point, Windows is almost a Swiss Army knife of computing, taking everything I’ve enjoyed from the Linux world without having to spend a few hours either setting up new hardware or reconfiguring everything after an update.)

How To Run 16-bit Windows Applications In 64-bit Windows

To use otvdm, download the latest release from GitHub, then unzip to the directory of your choice. From here, you can simply use otvdm as a portable installation by dragging and dropping your 16-bit application onto the otvdm.exe binary, and you’re all set!

If, like me, you prefer to have a more seamless integration into Windows, you can install otvdm with one of the included installer shortcuts. If you prefer to not show the console window while your application runs, use the “install (no console)” shortcut. At this point, 16-bit Windows applications (and their installers, for that matter) will run just like any other Windows application! Now, I’ll never get any work done ever again.

JezzBall
JezzBall on Windows 11!

How To Install Android Apps On Windows 11 Without Amazon

Microsoft has really leaned into the whole open source world since Staya Nadella took over in 2014, and that’s been pretty wonderful if you ask me. I am completely enamored with their use of GitHub for developing Windows modules, and especially with the Windows Subsystem for Linux that lets me run all my favorite Linux tools right from the convenience of Windows Terminal (which is also pretty awesome, by the way). While Apple has doubled-down on the closed-off, walled-garden ecosystem that they’ve been working on since the debut of the iPhone, Microsoft has gone in the opposite direction (to great benefit), embracing the same kinds of interoperability with Android devices through the Your Phone app. The only piece of the puzzle that’s been missing is the ability to run Android apps directly on the desktop which is where the new Windows Subsystem for Android comes in. Unfortunately, the system is immediately hobbled by having only the Amazon app store available, so we’ll need a way to get any and all apps (and app stores) installed. I generally prefer starting from the Google Play store (which has its own caveats, of course), so we’ll need to go through an alternative installation process to set up WSA rather than the straightforward installation via the Microsoft Store.

This tutorial is based on work previously put together by the WSA Community on GitHub with my own commentary to clarify or expand on the subject matter.

Install Windows Subsystem for Android and Windows Subsystem for Linux from the Microsoft Store

The first step in getting the Google version of WSA is to install the stock version (with Amazon) from the Microsoft Store. There are several dependencies that WSA requires, so this is the quickest and easiest way to have them installed on your machine. Once WSA is installed, you can skip signing into the Amazon App Store and uninstall the stock WSA.

To compile a custom version of WSA, we’re going to need a few tools that run exclusively in Linux (Android being based on the Linux kernel, but you knew that). Grab your preferred flavor from the Microsoft Store. I’m using Ubuntu because that’s the one I’m most familiar with (being my daily driver for half a decade). Once you have WSL installed, open a PowerShell terminal and type wsl --list --verbose to verify that your distro is running WSL version 2. If, for whatever reason, your distro is running WSL version 1, you’ll need to stop the WSL with wsl --shutdown and type the following command:

wsl --set-version <distro name> 2 where <distro name> is the name of your distro as listed when you ran the –list command earlier. This will take just a few moments, and you’ll be ready to continue!

Install Linux packages

If you’ve already set up your Linux distro as a tab in Windows Terminal, good on you! Open that tab and get ready to Bash. For the rest of you, start your distro by invoking the following in a PowerShell terminal:

wsl -d <distro name>

Now you’ve got your Linux distro up and running, so the following commands will be entered at the $ prompt (instead of the Windows > prompt):
sudo apt update
sudo apt install unzip lzip

Prepare Installation Folder

Back in Windows Explorer, create a folder at C:\WSA. This is going to be the working folder for our installation. Now, we need to download the installation package. However, since we’re going to be modifying the package, we can’t just grab it from the Microsoft Store (that’s what we did earlier). You’re also going to want to install a Zip archive manager like 7Zip or PeaZip.

Download the WSA installation package

We’re going to use a link generator service to get the installation package from the Microsoft Store’s repository. Navigate to https://store.rg-adguard.net and enter the following settings before clicking the check mark:

ProductID: 9P3395VX91NR

RP: Fast

You’ll be presented with a list of all the files related to that Product ID, but we’re looking for the *.msixbundle file extension associated with WindowsSubsystemForAndroid. The file should measure around 1.3GB. Download the package file to your C:\WSA folder and open it with your Zip manager. You’re going to see a lot of files with the *.msix extension, but sort them by size to find the biggest files. Find the one that matches your OS architecture (for example, WsaPackage_X.X.XXXXX.X_x64_Release-Nightly.msix for a 64-bit Windows) and extract it.

Now, extract the contents of the *.msix file to a new folder within C:\WSA. Locate and delete the following:

“AppxBlockMap.xml”

“AppxSignature.p7x”

“[Content_Types].xml”

and delete the “AppxMetadata” folder.

Download OpenGApps

Navigate to https://opengapps.org/ and download the Android 11.0 Pico variant for your architecture.

Save the Zip file in the C:\WSA folder, but don’t extract it.

Clone the GitHub Repo and Populate Directories

Fire up your WSL distro and mount your C:\WSA directrory so you can clone the WSAGAScript repo by running the following at your WSL ($) prompt:
cd /mnt/c/WSA
git clone https://github.com/WSA-Community/WSAGAScript

(NOTE: If this repository fails, I have a fork at https://github.com/airbornesurfer/WSAGAScript)

In Windows Explorer, go back to your extracted WsaPackage folder (the one you deleted files from earlier) and copy the following files into the C:\WSA\WSAGAScript#IMAGES folder:

product.img

system.img

system_ext.img

vendor.img

Lastly, copy the GApps Zip file downloaded earlier into C:\WSA\WSAGAScript#GAPPS (again, do not extract it).

Create the New Installation Package

Check the “VARIABLES.sh” file to verify that your architecture is set correctly, then set the permissions for the scripts that will create the new installation images. From your WSL terminal (you should still be in mnt/c/WSA/WSAGAScript), invoke the following command:

chmod +x *.sh

You can verify the scripts are now executable by invoking ls -l and checking that the *.sh files show “-rwxrwxrwx”. If all is set, then execute the scripts by invoking the following:

./extract_gapps_pico.sh
sudo ./extend_and_mount_images.sh
sudo ./apply.sh
sudo ./unmount_images.sh

Once complete, move the *.img files from the C:\WSA\WSAGAScript#IMAGES folder back to the WsaPackage folder you previously copied them from.

Register the New Installation Package and Install

Open Windows Developer Settings (search “Developer Settings” from the Start Menu) and enable Developer Mode. Close Windows Terminal and open a new PowerShell Terminal as Administrator, then invoke the following command: Add-AppxPackage -Register <path-to-extracted-msix>\AppxManifest.xml where <path-to-extracted-msix> is the path to the WsaPackage folder inside C:\WSA.

WSA will now install with GApps. Once complete, sign into the Google Play Store and install “Android System WebView” to make sure your apps don’t crash.

A Serial Terminal For Windows Terminal

Since switching to Windows 11, I have fallen in love with Windows Terminal–the built-from-the-ground-up terminal emulator for Windows that combines everything that I loved about Linux and MacOS with the functionality of tabbed windows and a serious dose of customization. However, because much of my command line work falls into communicating with an external device over serial, I wanted to be able to keep that workflow within Windows Terminal like I’m used to doing already. In other words, I didn’t want to have to resort to using a separate GUI like PuTTY when a command-line tool like Screen or Minicom would do just fine. The problem is that, since the removal of HyperTerminal in Windows Vista, Windows has not included a CLI solution for serial communication (which is kinda weird because Telnet is still buried in Windows 11; if the reasoning was because obsolescence, you’d think that Telnet would also get the axe).

Now, since I have Ubuntu installed, I could just install Screen or Minicom and call it a day, but WSL 2 does not support serial communication. If I wanted to use those tools, I would either need to change the WSL version every time I wanted to use the serial port or install another instance of Linux under WSL 1. I mean, it works, but I really just felt it inefficient to have to fire up Debian (the install is smaller than Ubuntu) just so I could use Minicom.

After a little more digging, I found Makerdiary’s Terminal-S. It’s a simple serial terminal written in Python that can be compiled as a self-contained exe. This little gem was exactly what I was looking for in terms of functionality! It automatically connects to the COM port (or drops a list of available ports) and connects using some default settings for baud rate, stopbit, and parity. I can fire up Windows Terminal, invoke the command in PowerShell, and I’m good to go!

Windows Serial Terminal

But this is Windows Terminal, and I have this lovely menu of drop-down presets that will automatically spawn the environment of my choice with some lovely aesthetic theming. So, I want to be able to just click on a new tab and get that full retro terminal feel without needing to pretend I’m even in Windows! What I need to do is alter the program just a smidge so that instead of looking for flags in the command-line structure (ie -b for setting baud rate), the program will just ask me what settings I want to use (including some defaults for simplicity). To do this, I simply altered the @click.command section to only look for serial ports and moved the connection settings to a series of prompts in the main function, like so:

"""
Terminal for serial port

Requirement:

    + pyserial
    + colorama
    + py-getch
    + click
"""

import os
if os.name == 'nt':
    os.system('title Serial Console')

from collections import deque
import sys
import threading

import colorama
import click
import serial
from serial.tools import list_ports


def run(port, baudrate = 115200, parity='N', stopbits=1):
    try:
        device = serial.Serial(port=port,
                                baudrate=baudrate,
                                bytesize=8,
                                parity=parity,
                                stopbits=stopbits,
                                timeout=0.1)
    except:
        print('--- Failed to open {} ---'.format(port))
        return 0

    print('--- {} is connected. Press Ctrl+] to quit ---'.format(port))
    queue = deque()
    def read_input():
        if os.name == 'nt':
            from msvcrt import getch
        else:
            import tty
            import termios
            stdin_fd = sys.stdin.fileno()
            tty_attr = termios.tcgetattr(stdin_fd)
            tty.setraw(stdin_fd)
            getch = lambda: sys.stdin.read(1).encode()

        while device.is_open:
            ch = getch()
            # print(ch)
            if ch == b'\x1d':                   # 'ctrl + ]' to quit
                break
            if ch == b'\x00' or ch == b'\xe0':  # arrow keys' escape sequences
                ch2 = getch()
                esc_dict = { b'H': b'A', b'P': b'B', b'M': b'C', b'K': b'D', b'G': b'H', b'O': b'F' }
                if ch2 in esc_dict:
                    queue.append(b'\x1b[' + esc_dict[ch2])
                else:
                    queue.append(ch + ch2)
            else:  
                queue.append(ch)

        if os.name != 'nt':
            termios.tcsetattr(stdin_fd, termios.TCSADRAIN, tty_attr)

    colorama.init()

    thread = threading.Thread(target=read_input)
    thread.start()
    while thread.is_alive():
        try:
            length = len(queue)
            if length > 0:
                device.write(b''.join(queue.popleft() for _ in range(length)))

            line = device.readline()
            if line:
                print(line.decode(errors='replace'), end='', flush=True)
        except IOError:
            print('--- {} is disconnected ---'.format(port))
            break

    device.close()
    if thread.is_alive():
        print('--- Press R to reconnect the device, or press Enter to exit ---')
        thread.join()
        if queue and queue[0] in (b'r', b'R'):
            return 1
    return 0

@click.command()
@click.option('-p', '--port', default=None, help='serial port name')
@click.option('-l', is_flag=True, help='list serial ports')

def main(port, l):
    port is None
    if port is None:
        ports = list_ports.comports()
        if not ports:
            print('--- No serial port available ---')
            return
        if len(ports) == 1:
            port = ports[0][0]
        else:
            print('--- Available Ports ----')
            for i, v in enumerate(ports):
                print('---  {}: {} {}'.format(i, v[0], v[2]))
            if l:
                return
            raw = input('--- Select port index: ')
            try:
                n = int(raw)
                port = ports[n][0]
            except:
                return
    baudrate = input("Enter baud rate (Default 115200): ")
    if (len(baudrate) == 0):
        baudrate = 115200
    parity = input("Enter parity [N,E,O,S,M] (Default N): ")
    if (len(parity) == 0):
        parity = "N"
    stopbits = input("Enter stop bit (Default 1): ")
    if (len(stopbits) == 0):
        stopbits = 1    
    while run(port, baudrate, parity, stopbits):
        pass

if __name__ == "__main__":
    main()

Of course, it took me a little bit to deconstruct the program (as well as re-learn Python, which I hadn’t really used in any significant capacity for half a decade at least), but now I have it working exactly how I want it to work, and it feels right! Of course, I had never used Python on Windows before, either, so wrapping my head around PowerShell has been enlightening as well (Yes, I’m late to the PowerShell party, so I’m making up for it). Once I figured out how to use Pyinstaller (after remembering how to set a PATH variable in Windows), then I just have to drop the portable EXE file into a nice, out of the way place in Windows (might as well put it in a folder in C:) and make sure that folder is added to the PATH variable.

Add a folder to PATH variable

Adding a folder or application to the global PATH variable is a pretty simple proposition in Windows. From Windows Explorer, right-click on “This PC” and select “Properties”. This will bring up the settings dialog for System > About. Just under the “Device Specifications” section, click “Advanced System Settings” to bring up the traditional System Properties window. Click on the “Advanced” tab, then the “Environment Variables” button at the bottom of the window.

The “Environment Variables” window is divided into to groups: one for the current user and one for the system. In the system group dialog, find and double-click the line for “Path” to edit it. Click the “New” button to add a new line and type in the path for the folder or application you wish to add to the system PATH. When you’re done, click “OK” to close the window and save, then click “OK” to close the Environment Variables window, and finally click “OK” to close the System Properties window.

Customize Windows Terminal

In Windows Terminal, open the settings dialog and click “Add A New Profile”. Fill in the settings as appropriate. I’ve posted mine as a model:


Retrotacular

Of course, the real draw here is giving the terminal tab a lovely old-school green phosphor look which we can do either using the settings GUI to turn on the “Retro terminal effects” (this setting simulates CRT scan lines and gives a nice anti-alias that simulates the phosphorescent glow of the characters on the monitor). I’m using the Cascadia Mono font at 16pt weight to get the look I’m going for and the “Vintage” cursor style will round everything out nicely. For the color scheme, add the following block of code to the settings JSON file, then enable the new “Green Phosphor” color scheme.

{
            "background": "#000000",
            "black": "#000000",
            "blue": "#00FF00",
            "brightBlack": "#00FF00",
            "brightBlue": "#00FF00",
            "brightCyan": "#00FF00",
            "brightGreen": "#00FF00",
            "brightPurple": "#00FF00",
            "brightRed": "#00FF00",
            "brightWhite": "#00FF00",
            "brightYellow": "#00FF00",
            "cursorColor": "#00FF00",
            "cyan": "#00FF00",
            "foreground": "#00FF00",
            "green": "#00FF00",
            "name": "Green Phosphor",
            "purple": "#00FF00",
            "red": "#00FF00",
            "selectionBackground": "#FFFFFF",
            "white": "#00FF00",
            "yellow": "#00FF00"
        }

From here, everything is ready to go! Connect a serial device, fire up the terminal, and you’re off to the races!