TroubleChute Logo
SOFTWARE PROJECTS

Creating the TcNo Account Switcher


1,444 Words, 7 Minutes.

Watch the video:


TcNo Account Switcher Banner

(Almost) no introduction necessary

The TcNo Account Switcher is my biggest project to date. There are over 603,000 downloads from GitHub alone and reliably over 15,000 users every day. This project has solved one of my biggest pain points, juggling multiple accounts.

This project and its modular system are described in detail on the project’s Wiki

TcNo Account Switcher

The Problem

Having an account for Steam, Epic Games, Ubisoft, EA, and so on. But juggling multiple accounts, such as an alternative accounts on each, is a lot of effort. Consider another Steam account for storing more items than the Steam inventory allows for a single account, or an account from another region, or from a friend, and so on. The account management quickly becomes a headache.

Having accounts managed from a centralized launcher is the perfect solution to this growing issue.

The Solution

The TcNo Account Switcher works by the fact that accounts stay logged-in once a user signs in. This cached state is stored somewhere, and just switching that data for data from another account allows users to be simultaneously logged into multiple accounts when this is not possible normally.

Years since this project’s release, Steam has finally incorporated a built-in account switcher, but with heavy limits, such as only being able to use up to 5 accounts.

Monitoring for file and registry changes when logging in, logging out, and closing/restarting programs like Steam allows me to quickly find where this information is stored. The process is described on the Wiki and in this video:

Watch the video:

Once data locations are found using WinMerge, Nirsoft RegistryChangesView, and SysInternals Process Monitor, they are added to the modular account switching platform system in a simple JSON text file here on GitHub.

Features

Difficulties

This project is absolutely massive in scope. Here are some of the most challenging issues that I overcame:

Patch Updates

While simple in theory, getting a patch system to work reliably was difficult. Currently, with the finalized process, when I push an update, the CI/CD builds the program (AppVeyor via GitHub Actions), signs (if necessary), and differences the new binaries and files with the old ones. Differences are compressed and uploaded to an FTP server, where they are distributed by a CDN. These differences are downloaded and applied to a user’s computer through another process.

The updater gets complex when: files need to have their contents verified through hashes; differences are applied; files in areas like Program Files are changed, requiring admin and even updating the updater. All of these were worked around.

Unfortunately, some users were stuck on versions with broken updaters, and as this “just worked, they never saw the need to update. Funny, actually. I’m happy that my software was reliable enough to not update, but also a little disheartened they didn’t get to try new features. Some may still not know there’s support for launchers other than Steam.

WPF

Wow. If you’ve ever used WPF to try and ‘skin’ elements, you know how difficult it is. While the language is great for customizing components, it’s only easy to a certain degree, until you basically need to rewrite entire components. While I followed this route for a while after moving to C#, I pursued using an embedded browser to get closer to other programs using libraries like Electron. This was a great choice both for animations, customizability, and so much more.

WebView2

One of the most surprising issues was running into issues with Microsoft’s own tool set. The WebView2 component, when used with the official .NET MAUI integration, has a few quirks. The project uses a custom title bar in HTML that allows minimizing, closing, and moving the window around on the screen. However, the ability to drag and drop elements is just missing. The title bar or accounts or platforms in their respective lists have the same issue. I hit this roadblock while updating to use Blazor and Direct Injection techniques and had to revert away from .NET MAUI because of this.

You can see the MAUI behavior on the github.com/dotnet/maui issues page [2022], then moved to github.com/MicrosoftEdge/WebView2Feedback [2022] was closed as Not Planned a year later [2023]. I followed the work as it was pushed as planned for the next version, then the next, and so on until I was forced to either replace the component entirely or revert to WPF.

Runtimes

While some runtimes auto-install on launch, using .NET Core and Microsoft WebView2 do not reliably come pre-installed, stay updated, or auto-install on launch. This process has to be handled by the programmer, or end user.

While downloading runtimes is easy and documented, automated runtime checks and installations are much better than users with preventable errors. The only way to create a program that doesn’t need runtimes is to use a much lower-level language or distribute the project with required runtimes. The latter of which ballooned download sizes, so C++ was chosen to check and install runtimes for the user.

The C++ wrapper (as any EXE in this project requires runtimes and can be launched through the CLI/Tray/Protocol and more) checks the Windows registry, compares versions, downloads, and installs required runtimes - once the user has confirmed these actions. While it is not perfect to have 2 EXEs per process, it is preferable to errors from the level of control the program wishes to give.

TcNo Account Switcher Runtime Installer Wrapper

Data storage directories

The program needs to store settings, accounts, and more. I originally picked next to the program; however, when installed to a folder like Program Files the program requires elevated permissions to run, such as Admin.

Moving to My Documents sounded good, as games and some programs store information there; however, users came across many issues, such as OneDrive interfering with its files.

Moving to %LocalAppData% was eventually chosen as the best location to store files and has worked perfectly since.

Updating architecture

During the project’s development, I learned a lot about databases, and started to explore languages other than C#, HTML/CSS/JS/PHP. At a stage, I was more than comfortable using Node.js, and no longer using Apache to host my website. Instead, I was hosting everything through Nginx, on an entirely different stack now using LEMP [Linux, Nginx, MySQL, PHP] instead of WAMP [Windows, Apache, MySQL, PHP].

I had not created software that I had supported for so long; I was changing the underlying technologies before, so this was a learning experience. I moved away from PHP entirely to instead use Express.js, and serve the same endpoints, maintaining support for older versions (still in use).

TroubleChute © Wesley Pyburn (TroubleChute)
Support Me Privacy Policy Cookies Policy Terms of Service Change privacy settings Contact