TaskAnalyzer
Shows what runs on the PC, which processes look unusual and why, and what eats the resources
TaskAnalyzer
A Windows desktop application that shows what runs on the computer, which processes look unusual and what uses the most resources. Every finding comes with its reason – the goal is not to deliver a verdict but to give enough information to judge for yourself.
TaskAnalyzer is not an antivirus. It works with heuristics, which by design produce false positives: an unsigned tool from a small developer gets points just like a genuinely suspicious file. A high score means "take a look", not "this is malware".
![]()
Running it
dotnet run --project src/TaskAnalyzer.App
Release build – one self-contained, portable exe (the same one the app store and the updater distribute):
dotnet publish src/TaskAnalyzer.App -c Release -r win-x64 -o publish
Requires Windows and the .NET 10 SDK to build. The shared updater (TomLabs.AutoUpdate.Avalonia) comes from
nuget.org, so a plain git clone is enough.
TaskAnalyzer --health prints {"status":"Healthy","version":"…","name":"taskanalyzer"} – the desktop
equivalent of a web app's GET /health.
Administrator rights
Without elevation the path, digital signature and command line of part of the processes (typically system processes and processes of other users) cannot be read. The app says so in the header and offers a restart as administrator. The analysis runs without it too, it just misses those processes – they are listed under Not verified.
The window
- Views in the sidebar: all processes, suspicious (score 15 and up), resource hogs, unsigned, not verified – each with a live count – and a snapshot summary (processes, total CPU, private memory, refresh interval).
- Process table sorted by risk score, then CPU; any column sorts on click. The filter box searches name, PID, path and description.
- Detail panel with every finding and its reason, path, command line, signature, parent process, user, elevation, start time, file age and size.
- Command palette (
Ctrl+K): jump to any process by name or PID, switch views, run actions. - Logs (
Ctrl+L): the application log live, filterable by level and text, plus the daily log files. - System / Light / Dark theme (
Ctrl+Shift+Lcycles, System follows Windows live), remembered for the next start; the version is in the header.
| Shortcut | Action |
|---|---|
Ctrl+K |
Command palette |
F5 |
Refresh now |
Ctrl+F |
Filter the table |
Ctrl+Shift+C |
Copy details of the selected process |
Ctrl+L |
Logs |
Ctrl+Shift+L |
Cycle the theme: system → light → dark |
What it collects
| Area | Source |
|---|---|
| Path of the executable | QueryFullProcessImageName (works without elevation) |
| Parent process, command line | WMI Win32_Process |
| User and elevation | process token (OpenProcessToken) |
| CPU, memory, threads, handles | System.Diagnostics.Process |
| Disk I/O | GetProcessIoCounters, difference between snapshots |
| Digital signature | WinVerifyTrust including catalog signatures (.cat) |
| File metadata | file version, creation date, size |
Rates (CPU, disk) are computed as the difference to the previous snapshot, so the first pass is only a reference and the values appear with the second refresh.
Rules
Every rule adds points to the risk score (0–100). The score is a plain sum capped at one hundred – a deliberately simple model, so the result can be explained.
| ID | What it looks for | Points |
|---|---|---|
| SIG001 | Unsigned executable | 20 |
| SIG002 | A signature exists but verification failed (e.g. the file was modified) | 40 |
| SIG003 | Unsigned file in the Windows system folder | 35 |
| SIG004 | Unsigned file in Program Files | 10 |
| LOC001 | Runs from a temporary folder (Temp) | 30 |
| LOC002 | Runs from the Downloads folder | 25 |
| LOC003 | Runs from the Recycle Bin | 45 |
| LOC004 | Runs from a drive root | 20 |
| LOC005 | Runs from AppData or ProgramData | 12 |
| IMP001 | System name (svchost.exe…) outside its expected folder |
45 |
| IMP002 | System process started by the wrong parent | 40 |
| TREE001 | Office application started an interpreter (macro in a document) | 40 |
| TREE002 | Browser started an interpreter | 25 |
| CMD001 | PowerShell with an encoded command (-enc) |
35 |
| CMD002 | PowerShell with a hidden window | 25 |
| CMD003 | PowerShell downloading content from the network | 30 |
| CMD004 | certutil with -urlcache or -decode |
35 |
| CMD005 | mshta running remote content |
40 |
| CMD006 | regsvr32 registering a remote object |
35 |
| CMD007 | bitsadmin transferring files |
30 |
| CMD008 | rundll32 running a script |
40 |
| CMD009 | wmic process call create |
30 |
| NAME001 | Double extension (invoice.pdf.exe) |
45 |
| NAME002 | Random-looking name outside the folders of installed software | 15 |
| AGE001 | Unsigned binary created within the last two days | 12 |
Findings RES001–RES005 (CPU, memory, disk, handles, threads) form a separate category and do not
raise the score – a memory hog is not the same as a suspicious process, and mixing both into one number
would only confuse. The table marks them with a purple dot.
Score levels: 60 and up high (red), 35 medium (amber), 15 low (grey), below 15 an outlined badge.
Tuning thresholds
The resource thresholds live in AnalyzerOptions – "a lot" means something else on a gaming PC than on an
office laptop. A new rule is an IProcessRule implementation added to RuleEngine.CreateDefaultRules().
Caveats when reading the results
- Windows recycles PIDs. When a parent process exits, its number may go to someone else. A parent–child
relation is therefore only accepted when both start times are known and the parent started first. Without
that,
svchost.exewould report a wrong parent all the time. - Catalog signatures. A large part of the system files carry no embedded signature but are signed in a
.catcatalog. Checking only the embedded signature would report half of Windows as unsigned. - Kernel pseudo-processes (
System,Registry, memory compression) hold thousands of handles even on a healthy system, so only their CPU usage is evaluated.
Log, settings, updates
- Log: Serilog, daily files
taskanalyzer-YYYYMMDD.login%LOCALAPPDATA%\TaskAnalyzer\logs, kept for 14 days; the level comes fromLogLevelin the settings. Each process is logged once when it first reaches a medium score, so an incident leaves a trace. Command lines of other processes are never logged. - Settings:
%APPDATA%\TaskAnalyzer\settings.json(theme, refresh interval, update channel, log level and folder).TASKANALYZER_DATA_DIRpoints the app at another folder. - Updates: through TomLabs.AutoUpdate from the TomLabs
app store (
https://apps.tomlabs.cz). The app checks at startup and every six hours, shows a banner in the status bar and verifies the signed manifest and the SHA-256 of the download. Builds frommastergo to the nightly channel,v*tags to stable (azure-pipelines.yml).
Structure
src/TaskAnalyzer.Core data collection and rules, no UI dependency
Collection/ process access, signatures, WMI
Analysis/Rules/ the individual heuristic rules
src/TaskAnalyzer.App Avalonia UI ("ops console" style shared with the other TomLabs desktop apps)
tests/ui-fixture settings for scripted UI runs (see CLAUDE.md)
tools/Make-Icon.ps1 regenerates icon.png and the exe icon
The core knows nothing about the UI, so a console tool or a periodic JSON export can be built on top of it.
Not there yet
- network connections of each process and correlation with autostart entries (Run keys, services, scheduled tasks),
- checking the hash against VirusTotal,
- metric history over time and a report export,
- ending a process directly from the app.
Changelog
Changelog
0.2.2 — 2026-09-24
Added
- The header button shows the current theme mode (half circle = System, sun, moon); the command palette can set each mode directly.
Changed
- The theme switch (header,
Ctrl+Shift+L) now cycles System / Light / Dark; System follows Windows live. Earlier Light/Dark choices were reset to System once. - The command palette's shadow follows the theme too.
0.2.1 — 2026-09-24
Changed
- The self-update library comes from nuget.org (TomLabs.AutoUpdate 0.3.2) instead of a git submodule; updates work as before.
0.2.0 — 2026-09-24
Changed
- New user interface on Avalonia in the shared TomLabs "ops console" style: sidebar with views and live counts (all, suspicious, resource hogs, unsigned, not verified), process table with a detail panel, status bar.
- Everything is in English now – the interface, the finding texts and reasons, and the documentation.
- The low-risk badge is grey instead of green, and scores below 15 get an outlined badge, so nothing that was flagged looks "fine".
Added
- The version of the build in the header;
TaskAnalyzer --healthprints the health document. - Light and dark theme with a switch in the header (
Ctrl+Shift+L), remembered for the next start. - Command palette (
Ctrl+K): jump to any process by name or PID, switch views, run actions. - Application log in daily files under
%LOCALAPPDATA%\TaskAnalyzer\logsand a Logs page (Ctrl+L) with the live log, level and text filter and the log files; each process is logged once when it first reaches a medium score. - Automatic updates from the TomLabs app store with a banner in the status bar.
- Application icon.
- The refresh interval is remembered.
0.1.0 — 2026-08-28
Added
- First version (WPF): process collection with path, parent, command line, user, elevation, CPU, memory, disk I/O and Authenticode signatures including catalog signatures.
- Eight rules with 25 detections and a risk score 0–100 with the reason of every finding; resource usage as a separate category that does not raise the score.
- Summary tiles, table with filters, detail panel and automatic refresh; restart as administrator.