Unfucked.Windows
0.0.1-beta.3
dotnet add package Unfucked.Windows --version 0.0.1-beta.3
NuGet\Install-Package Unfucked.Windows -Version 0.0.1-beta.3
<PackageReference Include="Unfucked.Windows" Version="0.0.1-beta.3" />
<PackageVersion Include="Unfucked.Windows" Version="0.0.1-beta.3" />
<PackageReference Include="Unfucked.Windows" />
paket add Unfucked.Windows --version 0.0.1-beta.3
#r "nuget: Unfucked.Windows, 0.0.1-beta.3"
#addin nuget:?package=Unfucked.Windows&version=0.0.1-beta.3&prerelease
#tool nuget:?package=Unfucked.Windows&version=0.0.1-beta.3&prerelease
🧰 Unfucked
Fix egregiously broken or missing functionality in .NET libraries. Inspired by underscore, jQuery, Apache Commons, Spring, and Guava.
Packages
General
- Comparables
- Clip a value to a specified range (also known as clamping, limiting, and truncating)
- Console
- Colored text and background in strings, not tightly coupled to
Console.Write
- Enable colored output on Windows 10 1511 and later
- Clear screen and move to top-left corner
- Cancel a
CancellationToken
when the user presses <kbd>Ctrl</kbd>+<kbd>C</kbd>
- Colored text and background in strings, not tightly coupled to
- Cryptography
- Random string generation
- Is certificate temporally valid
- Decimal math
Math
operations on 128-bitdecimal
values
- Directories
- Delete without throwing an exception on missing directories
- DNS
- Fluent resolving method
- If you need to resolve anything other than an A or AAAA record, take a look at DnsClient.NET instead
- Enumerables
- Filter out
null
values - Add multiple values at once
- Upsert into non-concurrent dictionary
- Fluent set difference method
- Filter out consecutive duplicate values
- Convert
IAsyncEnumerator
to list - First item or
null
instead ofdefault
for value types - Head and tail
- Delta changeset between two enumerables (created, updated, deleted, and unchanged items)
- Atomic swap on
ConcurrentDictionary
to upsert new value and get old value - Get or add to
ConcurrentDictionary
and dispose of created but unadded values - Get or add to
ConcurrentDictionary
and determine whether a new value was added or an existing value was returned - Polyfill for
IList<T>.AsReadOnly
for .NET versions before 8, including .NET Standard - Factories for singleton Dictionaries, Sets, and enumerables of key-value pairs
- Filter out
- Paths
- Trim trailing slashes
- Create new empty temporary subdirectory in specific parent directory
- Convert DOS backslashes to Unix forward slashes
- Match file extension against a set
- Processes
- Command line argument marshalling with correct escaping and quoting
- String to array
- Array to string
- Run program and get output and exit code
- Command line argument marshalling with correct escaping and quoting
- Strings
- Coerce empty strings to
null
- Fluently check if a string has any non-whitespace characters
- Fluently check if a string has any characters
- Fluent join method
- Uppercase first letter
- Lowercase first letter
- Trim multiple strings from start, end, or both
- Join enumerable into an English-style list with commas an a conjunction like
and
- Fluent conversion method to byte array
- Fluent conversion method to byte stream
- Convert DOS CRLF line breaks to Unix LF line breaks
- Repeat a string a certain number of times
- Polyfill for
StringBuilder.AppendJoin
in .NET Standard 2.0 - Polyfill for
string.StartsWith(char)
andstring.EndsWith(char)
in .NET Standard 2.0 - Polyfill for
string.Contains(string, StringComparison)
in .NET Standard 2.0
- Coerce empty strings to
- Tasks
- Unbounded delay time (.NET 6 tops out at 49.7 days)
- Await multiple tasks and proceed when any of them both completes and the return value passes a predicate, or they all fail to complete or the predicate
- Return
true
if any passed orfalse
if they all failed - Return the first passing task's result, or
null
if they all failed
- Return
- Asynchronously await the cancellation of a
CancellationToken
without blocking the thread
- URIs
- Fluent method to get URI query parameters
- Check if a URI host belongs to a given domain (site locking)
- Builder pattern for URLs
- Truncate URIs to remove the fragment, query parameters, or path. Useful for getting the origin too.
- XML
- Fluent methods to read an XML document from an HTTP response body as a mapped object, DOM, LINQ, or XPath
- Find all descendant elements of a parent node which have a given tag name
Caching
- Type-safe in-memory cache
Compression
- For use with SharpCompress
- Added features for TAR archives
- Symlinks
- Directories
- File permissions
- File owner
- File group
DateTime
- For use with NodaTime
- Absolute value of a
Duration
(likeTimeSpan.Duration()
)ZonedDateTime a, b; var abs = (a - b).Abs();
- Get midnight from a
ZonedDateTime
as aZonedDateTime
,Period
, orDuration
ZonedDateTime now = SystemClock.Instance.InTzdbSystemDefaultZone().GetCurrentZonedDateTime(); ZonedDateTime midnight = now.AtStartOfDay(); Duration sinceMidnight = now.LocalDateTime.TimeOfDay.ToDurationSinceStartOfDay(); Period sinceMidnight2 = now.LocalDateTime.TimeOfDay.ToPeriodSinceStartOfDay();
- Convert time zone offset to hours
double hours = DateTimeZoneProviders.Tzdb["America/Los_Angeles"].GetUtcOffset(SystemClock.Instance.GetCurrentInstant()).ToHours();
- Compare two
OffsetDateTimes
to see which one happens firstOffsetDateTime a, b; bool isBefore = a.IsBefore(b); isBefore = !b.IsAfter(a);
- More succinct and interchangeable way to define standard
TimeSpan
,Period
, andDuration
instances by force casting integral numbers to or constructingMilliseconds
,Seconds
,Minutes
,Hours
, andDays
, all of which implicitly convert toTimeSpan
,Period
, andDuration
TimeSpan t = (Seconds) 3;
DI
- For use with Microsoft.Extensions.Hosting dependency injection/inversion of control
- Add a colored console with column formatted data
HostApplicationBuilder builder = new(); builder.Logging.AddUnfuckedConsole();
- Search for JSON configuration files in executable directory, not just current working directory
HostApplicationBuilder builder = new(); builder.Configuration.AlsoSearchForJsonFilesInExecutableDirectory();
- Allow provider functions to be injected, so long-lived consumers can depend on short-lived dependencies and control their lifecycle
HostApplicationBuilder builder = new(); builder.Services .AddInjectableProviders() .AddSingleton<MyService>() .AddTransient<MyDependency>(); class MyService(Provider<MyDependency> dependencyProvider){ void run(){ using MyDependency dependency = dependencyProvider.Get(); } }
- Change the exit code with which the program exits when a background service crashes, instead of 0 which incorrectly indicates success.
HostApplicationBuilder builder = new(); builder.Services.SetExitCodeOnBackgroundServiceException(1);
- Easily register a class in the DI context as both itself and as all of its interfaces automatically, so you can inject it as any of the interfaces without any casting in constructors or unmaintainable multiple registration clutter
HostApplicationBuilder builder = new(); builder.Services.Add<MyService>(registerAllInterfaces: true); class MyService: MyInterface; class MyDependent(MyInterface dependency);
HTTP
- Inspired by JAX-RS and Jersey for Java
- Drop-in subclasses of
HttpClient
andHttpMessageHandler
and extension methodsHttpClient http = new UnfuckedHttpClient(); // set the subclass http = new HttpClient(new UnfuckedHttpHandler()); // or set the handler http = new UnfuckedHttpClient(new SocketsHttpHandler(){ AllowAutoRedirect = false }); // custom handlers are wrapped automatically
- Immutable builder pattern for HTTP request URLs, headers, verbs, and response representations that is fluent, composable, and avoids accidentally reusing stale state and sending to corrupted URLs
JsonNode responseBody = await http.Target("https://httpbin.org") .Path("get") .Accept(MediaTypeNames.Application.Json) .Get<JsonNode>();
- Request and response filtering
PrintRequests filter = new PrintRequests(); http.Register((ClientRequestFilter) filter); http.Register((ClientResponseFilter) filter); class PrintRequests: ClientRequestFilter, ClientResponseFilter { public async Task<HttpRequestMessage> Filter(HttpRequestMessage request, CancellationToken cancellationToken) { Console.WriteLine(">> {0} {1}", request.Method, request.RequestUri); return request; } public async Task<HttpResponseMessage> Filter(HttpResponseMessage response, CancellationToken cancellationToken) { Console.WriteLine("<< {0} {1}", (int) response.StatusCode, response.RequestMessage?.RequestUri); return response; } }
- Type-safe property registration
// set on shared client or ClientConfig http.Property(PropertyKey.JsonSerializerOptions, new JsonSerializerOptions()); // set on immutable request target WebTarget target = http.Target("https://httpbin.org") .Property(PropertyKey.ThrowOnUnsuccessfulStatusCode, false);
- Automatic response deserialization to given types from XML, JSON, and pluggable custom representations
// automatically mapped from JSON or XML depending on response content type, falling back to content sniffing MyClass response = await http.Target(url).Get<MyClass>();
- Rich exception class hierarchy
try { string response = await http.Target(url).Get<string>(); } catch(NotFoundException) { // 404 } catch(NotAuthorizedException) { // 401 } catch(ServerErrorException) { // 5xx } catch(WebApplicationException) { // any unsuccessful status code } catch(ProcessingException) { } // network or deserialization error, like DNS, connection refused, timeout
- Mockable and verifiable in unit or layer tests
ICS
- For use with Ical.Net
- Asynchronously serialize iCalendar files to a byte stream, to prevent Kestrel and IIS errors on synchronous I/O
- Converters between the three implementations of a datetime used by Ical.Net, NodaTime, and .NET
OBS
- For use with OBSClient
- Interface for Open Broadcaster Software Studio WebSocket API client to allow mocked testing isolation
- Easily connect and authenticate to servers without all the boilerplate
PGP
- For use with PgpCore
- Detached signing, where an ASCII-armored PGP signature is generated in a sidecar file, not inline wrapping the file being signed like in clearsigning
STUN
- For use with Stun.Net
- STUN client that retains the server that it was configured with, useful for error logging
- Multi-server STUN client that transparently picks a random public STUN server from a constantly-updated list when sending a request, with retries and fallbacks if any of them fail
- Thread-safe multi-server STUN client that can be used concurrently from multiple threads without conflicts
Twitch
- For use with TwitchApi.Net
- Interface for Twitch HTTP API client to allow mocked testing isolation
Windows
- For use with Managed Windows API (mwinapi)
- Reliably detect when computer is entering and exiting standby
- Kill the running screensaver
- Easier to get program's basename without memory leaks
- Get parent process of a process
- Get descendant processes recursively of a process
- Get locale of the operating system, rather than the user
- Convert between Win32 window handles, UI Automation elements, and mwinapi window instances
- Easily get all children of a UI Automation element
- Create a UI Automation property AND or OR condition that doesn't crash if there is only one sub-condition
- 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
- 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 usingConsole.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();
Related packages
Bom.Squad
Reconfigure the static shared Encoding.UTF8
instance to not emit UTF-8 byte order marks to unbreak compatibility with non-Microsoft software.
DarkNet
Turn the native Windows title bars dark in WPF and Windows Forms windows.
DataSizeUnits
Parse, convert, normalize, and format amounts of data like bits, bytes, kilobytes, and megabytes.
HidClient
Automatically connect and reconnect to USB HID peripherals.
KoKo
Automatically implement INotifyPropertyChanged
to allow you to create composable properties with no publisher or subscriber boilerplate or circular references.
SolCalc
Calculate a stream of solar time of day transitions for a given point on Earth, including sunrise, sunset, astronomical dawn and dusk, nautical dawn and dusk, and civil dawn and dusk.
ThrottleDebounce
Throttle, debounce, and retry functions and actions.
UnionTypes
Implicitly cast multiple types to one union type, to avoid manually writing millions of method overloads.
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net6.0-windows7.0 is compatible. net7.0-windows was computed. net8.0-windows was computed. net9.0-windows was computed. net10.0-windows was computed. |
.NET Framework | net462 is compatible. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
-
.NETFramework 4.6.2
- mwinapi (>= 0.3.0.5)
- ThrottleDebounce (>= 3.0.0-beta3)
- Unfucked (>= 0.0.1-beta.5)
-
net6.0-windows7.0
- mwinapi (>= 0.3.0.5)
- ThrottleDebounce (>= 3.0.0-beta3)
- Unfucked (>= 0.0.1-beta.5)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
Version | Downloads | Last Updated |
---|---|---|
0.0.1-beta.3 | 0 | 6/24/2025 |
0.0.1-beta.2 | 92 | 6/6/2025 |
0.0.1-beta.1 | 94 | 4/12/2025 |
0.0.0-beta5 | 136 | 3/11/2025 |
0.0.0-beta4 | 171 | 3/6/2025 |
0.0.0-beta3 | 67 | 9/30/2024 |
0.0.0-beta2 | 52 | 9/8/2024 |