Skip to content

Software License Dongle for F# .NET

F# consumes the same KeyNub.LicenseDongle assembly as C# and VB.NET — there is no separate binding. What changes is that three of F#’s ordinary idioms each remove a piece of ceremony the other two languages have to write out.

NuGet version badge

dotnet add package KeyNub.LicenseDongleCode language: Bash (bash)

Reading a License

open KeyNub.LicenseDongle

use ctx = LicenseDongleContext.Create()

let devices = ctx.Enumerate()
if devices.Count = 0 then
    printfn "Please plug in your KeyNub license dongle."
    0
else
    use dongle = ctx.Open()                  // first dongle found
    dongle.VerifyGenuine() |> ignore         // throws unless genuine
    use session = dongle.OpenSession()
    let licence = session.ReadRecord("license")
    0Code language: F# (fsharp)

Three Things F# Does Better Here

use instead of nested using. Each resource is disposed when its scope ends, without the indentation stack that the C# and VB.NET versions build up. With a context, a dongle and a session in play that is three levels saved.

Pattern matching instead of a catch ladder. Matching on the exception type reads as a decision rather than a sequence of filters:

with
| :? DeviceNotFoundException ->
    printfn "The dongle was disconnected while we were talking to it."
    0
| :? LicenseDongleException as ex ->
    eprintfn "KeyNub error (%O): %s" ex.Status ex.Message
    1Code language: F# (fsharp)

Structural equality on arrays. Verifying an app-crypto round trip is a single =, where C# and VB.NET both need an explicit element loop or a call to a comparison helper:

let recovered = session.AppDecrypt(sealedBlob)
if recovered = needed then "intact" else "MISMATCH"Code language: F# (fsharp)

One Thing to Watch

F#’s printf is type-checked, so the format specifier has to match. ProtocolVersion and FirmwareVersion are System.Version objects rather than strings, which means %O and not %s. That is a compile error rather than odd output at run time.

Do Not Gate on a Boolean

Where a licence check belongs is the same argument as everywhere else, : encrypt the data your program cannot compute, ship it encrypted, and decrypt it through the dongle at run time. Then removing the check does not unlock the feature — it removes the feature’s input.

Full F# sample on GitHub · the same thing in C# · in VB.NET

Shipping the Native Library with a F# Application

The KeyNub.LicenseDongle NuGet package carries the native library for every platform under runtimes/<rid>/native/: win-x86, win-x64, win-arm64, linux-x64, linux-arm64 and osx. On .NET 8 and later the host picks the right one at run time, and a framework-dependent or self-contained dotnet publish for a runtime identifier takes exactly that one. On .NET Framework, through netstandard2.0, the package’s MSBuild targets copy the library next to your executable and the binding pre-loads it.

Nothing else is deployed: no driver, no service, no registry entry. Single-file publishing and trimming work, because the native library is a plain file beside the executable rather than something the linker sees. On Linux, install the udev rule from NATIVES.md once, so that ordinary users may open the device.

Questions F# Developers Ask

Which .NET Versions Does the Binding Support?

The assembly targets net8.0 and netstandard2.0, so it runs on .NET 8 and later and on .NET Framework 4.6.1 and later, on Windows, Linux and macOS.

Does a F# Application Need Administrator Rights to Talk to the Dongle?

No, and no driver either: the dongle is a USB HID device that the operating systems handle with their built-in class drivers. On Linux, install the shipped udev rule once so that ordinary users may open it; without the rule the SDK reports access denied and names the cause in its error detail.

Does a F# License Check Need an Internet Connection?

No. Verification is a local exchange between your program and the dongle over USB: the SDK checks the dongle’s certificate chain to KeyNub’s root and runs a live challenge-response. There is no activation server and no account, so the check works on air-gapped machines.

Who Can Read the License Records on a Dongle?

Anyone holding the dongle: a program opens a session and reads records, and can decrypt data sealed for that dongle. Writing records, erasing them and incrementing counters need your write key. What the dongle guarantees is that none of it is available without the dongle present.

Can a License Written from F# Be Read by a Program in Another Language?

Yes. Every binding drives the same core library and the same dongle, and records and sealed data are language-neutral bytes. Your issuing tool can be written in one language and your product in another.

All supported languages · All industries · Buy a KeyNub · Ask us something