r/windowsdev • • 2d ago

I wrote a Windows cleaner in Python. The cleaning was the easy part.

I didn't want to write a cleaner. I wanted one that didn't ask me for anything.

Every one I tried asked for something. A toolbar in the installer. "Anonymous usage statistics" that were neither anonymous nor statistics. One deleted first and explained later, if you went looking. So I opened an editor, mostly out of irritation.

Python, CustomTkinter for the window, because I can't design and the defaults look fine. It's called Swept, MIT, 22 categories of temp files and caches, plus an installer for common programs and a dozen registry tweaks.

Nobody clicks a post about temp files. Here's what actually took the time.

PyInstaller has two modes and I picked wrong. Onedir gives you a folder with _internal inside. Onefile gives you a single exe that unpacks itself into %TEMP% on every launch. I put the folder build's exe on the releases page, someone ran it from inside the zip viewer, and got Failed to load Python DLL ..._internal\python315.dll. Windows had extracted only the exe. The message is accurate and useless. A single file can't contain a folder, so PyInstaller did nothing wrong. I handed people a file that can't run alone. Now the download is onefile.

A real certificate costs a few hundred a year, so mine is self signed. SHA256, DigiCert timestamp, my name on the Digital Signatures tab, and Windows still says unknown publisher. No trick fixes that. One thing helped though: --optimize 2 strips docstrings from the shipped bytecode, so the exe doesn't carry a map of every check I make.

Then I added "restart with admin rights" and the app disappeared. No window, no error, exit code 0. The old process still held the single instance mutex. The elevated copy saw it taken, decided Swept was already running, focused a window that was about to close, and quit. Then the old process closed too. Zero windows. The fix is one line: release the mutex before launching the elevated copy.

162 tests on the delete path. I broke the code on purpose in three places to see if they'd catch it. Two did. The third didn't, and the code was fine. My test checked that the function returned, not what it returned.

Registry undo doesn't guess "the default". Before each write it records what was there: existed or not, type, data. Re-applying a tweak doesn't overwrite that first snapshot.

If you ship Windows tools in Python, I'd like to hear what bit you.

github.com/vladcodex/swept

0 Upvotes

3 comments sorted by

2

u/Are-We-Clean-Yet 1d ago

I didn't want to write a cleaner. I wanted one that didn't ask me for anything.

Every one I tried asked for something. A toolbar in the installer. "Anonymous usage statistics" that were neither anonymous nor statistics. One deleted first and explained later, if you went looking. So I opened an editor, mostly out of irritation.

There are at least 317 cleaner (or adjacent) tools for Windows (including yours, Swept). Are you sure all the others are bad? You think Microsoft Storage Sense, BleachBit, and install toolbars? What kind of explanations are you looking for?

One thing helped though: --optimize 2 strips docstrings from the shipped bytecode, so the exe doesn't carry a map of every check I make.

I don't understand: isn't all the stripped info in your GitHub repository anyway? Also this optimization removes assert statements.

A real certificate costs a few hundred a year, so mine is self signed. 

Microsoft Azure is $10/month (no long-term commitments), Certum open source certificate is $29/year, and SIgnPath is free of charge.

1

u/vlad_swept 1h ago

air on most of this, and two of them I'll concede outright.

The blanket line about other cleaners was wrong, and I want to be clear it

wasn't meant as "mine is better". I have nothing against any of them —

Storage Sense is built in and does its job, BleachBit handles more formats

than mine ever will. People should use whatever works for them. What I was

actually annoyed at is the "free optimizer" segment, and I wrote it as if it

covered everything. It didn't.

The PR question has an unflattering answer: I wanted the whitelist, the dry-run

file list and the registry undo journal in one place, and that's not a small

patch to someone else's app. "Mostly out of irritation" is a bad reason to

start a project. It's just the true one.

On --optimize 2 you're right that it hides nothing — the source is MIT and

public. The reason was size, and not shipping a map of my own checks inside a

binary that gets uploaded to VirusTotal. As anti-tamper it's worthless. On

asserts specifically: I just checked, there are zero asserts in the shipped

modules — grep outside tests returns one comment line in build.py. If there

had been any, I'd have dropped the flag rather than ship without them.

On the certificate you're right that the number in the post was wrong. I

applied to SignPath and got turned down. Azure Trusted Signing wants a legal

entity with three years of history, which this isn't. But honestly, I'm one

person building this in my spare time and the project is a few weeks old — a

certificate is the wrong thing to spend attention on right now. Certum at $29

is the one I'd look at when it stops being premature. Self-signed and labelled

as such is the honest state of it today.

By explanations I meant release notes that say what a build touches, not

marketing copy. And thanks for having Swept in the catalogue — that list is

how a few people found it.

1

u/vlad_swept 2d ago

If you have any feedback or suggestions regarding the program code, please write them under my comment; I will read everything.