Same as nice but for Windows. Same same but different...
This is a simple (or better, simplistic) program that mimics Unix's own
nice. Hope it'll keep you entertained.
Because (back in 2016) I couldn't find any easy-peasy way to start a process from Java with a given priority class. I first tried my luck with the obvious:
cmd /c start /belownormal /wait /b my.exe some args
But the Java ProcessBuilder didn't quite like that and gave me endless
trouble with stream redirection. So I started looking for a stinking,
standalone exe I could just dump on any recent Windows box and that
depended only on libraries already shipping with Windows, so I could
easily bundle it with a Java app. That ruled out my first candidate, GNU
Core Utils. So I watched the GUI parade coming out of my Google search.
Entertaining, but not exactly what I was hoping for. Then I Googled some
more. And more. After a whole day of scratching around (ya, my Google-foo
must suck!) I came to the conclusion that I might just as well spend the
next day writing it myself, and that's what I did.
In 2026, PowerShell and other tools probably make winice redundant, but
I'll keep it here just in case anyone needs it for old Windows setups. Yep,
Winice's slogan is:
- drop one exe onto as many (possibly quite old) Windows machines as possible
Very similar to nice on Unix.
nice [-n niceness] [COMMAND [ARG]...]
Runs COMMAND with a niceness value, which affects process scheduling.
If you specify a COMMAND but no niceness (i.e. no -n option) then it runs
COMMAND with a niceness value of 10. With no COMMAND and no niceness,
it just prints the current niceness value to stdout.
Niceness values range from -20 (most favorable to the process) to 19
(least favorable to the process) and are converted to Windows priority
classes as listed below. (In each range, values are inclusive.)
-20to-15: Real Time-14to-8: High-7to-1: Above Normal0to6: Normal7to13: Below Normal14to19: Idle
Any value less than -20 has the same effect as -20. Likewise, any
value greater than 19 has the same effect as 19. In the reverse
direction, priority classes map to niceness values
as listed below.
- Real Time:
-19 - High:
-14 - Above Normal:
-7 - Normal:
0 - Below Normal:
7 - Idle:
14
Note that to run a process with a Real Time priority, you need to have
admin rights. If you use nice as a normal user and specify any niceness
value less then -14, you get a priority of High. For example, this is
what you get with no admin rights when nice-ing nice itself:
> nice -n -20 nice
> -14But if you run the same command as an admin, you get:
> nice -n -20 nice
> -19That is, this time you get a priority of -19 = Real Time.
Download the latest release. Just grab the nice.exe
binary file and dump it into some directory. (You may also want to add
that directory to your PATH.) winice needs the .NET framework 4.8
or above to run. (The release page details supported Windows/.NET versions
and install instructions.)
If you have an ancient Windows setup, you should probably download the 2016 release. It has slightly less features, but it'll do a decent job.
The program is written in C#, targeting .NET 10. (We targeted .NET
4.8 up to v1.1.0, but in 2026, it looks like .NET
10 sort of strikes the right balance between broad backward compat
and future proofing.)
The code is pretty straightforward. The main is in the Program class.
The first step is to parse the command line arguments to figure out what
task to run. Each task implements the ITask interface and gets fed the
parsed command line arguments. Currently there are only two tasks: the
one to print the current niceness value and the other to run a process
with a given scheduling priority. I'm pretty sure you can figure out the
rest on your own...
Build and run locally using the Nix flake in the nix dir.
(Nix buys us reproducibility and local-first CI/CD. We used
to have a GitHub CI/CD pipeline, but we don't need that
any more since Nix makes sure builds are reproducible across dev and
server machines.)
Once you're ready to release,
- decide on the semantic version number, e.g.
2.1.5 - update the
versionattribute innix/winice/util.nixaccordingly - merge your branch into
master - tag the release using the format
vM.m.p(sem ver), e.g.git tag v2.1.5 - push the tag, e.g.
git push origin v2.1.5 - build the release, e.g.
nix build nix/#winice-fdd-osx-arm64,nix build nix/#winice-scd-osx-arm64, etc. - create a GitHub release from the tag, upload the Nix-built release artefacts, include release notes, supported versions, install instructions, etc.