Skip to main content
.NETFramework4.6.2net6.0-windows7.0

Fix egregiously broken or missing functionality in .NET libraries that integrate with Windows APIs.

Published
Jul 5, 2026
3mo ago
Total Downloads
2.6K
2,593

Install

dotnet add package Unfucked.Windows --version 0.0.1-beta.12
ProductVersions
.NET
net6.0-windows7.0
Other
.NETFramework4.6.2

README

🧰 Unfucked.Windows

NuGet GitHub Actions Testspace Coveralls

Fix egregiously missing or broken functionality in .NET libraries that integrate with Windows APIs.

Unfuck your house

Installation

dotnet package add Unfucked.Windows
using Unfucked;
using Unfucked.Windows;

Usage

Arguments

  • Command line argument marshalling with correct escaping and quoting
    • String to array
      IEnumerable<string> argv = WindowsProcesses.CommandLineToEnumerable("arg1 arg2");
      
    • Array to string (in the Unfucked library, Unfucked.Windows is not required)
      string args = Process.CommandLineToString(["arg1", "'argument' \"2\""]);
      
  • Get command line for processes not started by the current process, includes program filename
    • One big string
      string commandLine = process.CommandLine;
      // "C:\path\to\myprogram.exe --arg1 --arg2"
      
    • Split into tokens
      IEnumerable<string> commandLine = process.CommandLineSplit;
      // ["C:\path\to\myprogram.exe", "--arg1", "--arg2"]
      

Console

  • Detach a console application from its console window if you want to prevent it from receiving Ctrl+C, because it's a child process of your console application, you're handling that signal in your parent process using Console.CancelKeyPress, and you don't want the console sidestepping your parent and killing your child.
    using Process child = Process.Start("child.exe", "args")!;
    child.DetachFromConsole();
    

Internationalization

  • Get locale of the operating system, rather than the user
    CultureInfo machineCulture = Cultures.CurrentMachineCulture;
    

Processes

  • Easier to get program's basename without memory leaks
    string? basename = SystemWindow.ForegroundWindow.ProcessExecutableBasename;
    
  • Get parent process of a process
    using Process? parent = Process.GetCurrentProcess().Parent;
    parent = Process.GetParentProcess(childPid);
    
  • Get descendant processes recursively of a process
    IEnumerable<Process> decendants = Process.GetCurrentProcess().Descendants;
    
  • Suspend or resume a process
    using Process process = Process.GetProcessById(pid)
    bool isSuspended = process.Suspended;
    process.Suspended = true;
    process.Suspended = false;
    
  • Detect if a process is elevated (running as administrator)
    bool isElevated = Process.GetCurrentProcess().IsProcessElevated();
    
  • Get process command line, even for processes not started by this process

Security

  • Determine if the user who ran a process is a member of the Administrators group, and if it's running elevated.

    WindowsIdentity.GetCurrent().AdministratorElevation
    
      ElevatedAdmin
      User is an administrator, and the process is running elevated
      UnelevatedAdmin
      User is an administrator, but the process is not running elevated
      NotAdmin
      User is not an administrator, and cannot run any processes elevated
    

Standby and screensaver

  • Reliably detect when computer is entering and exiting standby
    using IStandbyListener standbyListener = new EventLogStandbyListener();
    standbyListener.StandingBy += (_,_) => Console.WriteLine("The computer is entering sleep mode");
    standbyListener.Resumed += (_,_) => Console.WriteLine("The computer woke up from sleep mode");
    
  • Kill the running screensaver
    new ScreensaverKiller().KillScreensaver();
    

Storage

  • Get a file's size on disk. This can be larger than the file's intrinsic size because of cluster size rounding up, or it can be smaller due to NTFS compression or sparse (e.g. partially downloaded) files.
    ulong sizeOnDiskBytes = new FileInfo("filename.txt").LengthOnDisk;
    

UI Automation

  • Convert between Win32 window handles, UI Automation elements, and mwinapi window instances
    AutomationElement? automationElement = SystemWindow.ForegroundWindow.ToAutomationElement();
    SystemWindow foreground = foregroundUiaElementd.ToSystemWindow();
    IntPtr? foregroundHwnd = automationElement.ToHwnd();
    
  • Easily get all children of a UI Automation element
    IEnumerable<AutomationElement> children = automationElement.Children();
    
  • Create a UI Automation property AND or OR condition that doesn't crash if there is only one sub-condition
    IEnumerable<string> allowedNames = ["A"];
    automationElement.FindFirst(TreeScope.Children, UIAutomationExtensions.SingletonSafePropertyCondition(AutomationElement.NameProperty, false, allowedNames));
    
  • Find a child or descendant UI Automation element and wait if it doesn't immediately exist, instead of returning null, to prevent UI rendering race conditions
    AutomationElement? a = automationElement.WaitForFirst(TreeScope.Children, new PropertyCondition(AutomationElement.NameProperty, "A"), TimeSpan.FromSeconds(30), cancellationToken);
    

All Unfucked libraries

Changes from Previous Version

No structural changes between v0.0.1-beta.11 and v0.0.1-beta.12.

Adoption Assessment

Assess this package against its supported frameworks, license, maintenance signals and dependency graph before making it a project standard.

This version is marked prerelease. Validate its API and upgrade path before production use.Compatibility metadata lists 2 target frameworks; confirm the exact target used by your application.

Related Guides & Workflows

Learn how to evaluate, integrate, or audit this package in your .NET project.