Lizenzaktivierung in MAUI
Diese Anleitung zeigt, wie Sie die Lizenzaktivierung mit Babel Licensing in einer .NET-MAUI-Anwendung implementieren. Mit diesem Ansatz binden Sie Lizenzen sicher an bestimmte Geräte und stellen so sicher, dass Ihre Software nur gemäß Ihren Lizenzbedingungen verwendet wird. Wenn Sie diesem Implementierungsmuster folgen, entsteht ein robustes Lizenzierungssystem, das auf mehreren Plattformen einheitlich funktioniert und dabei die plattformspezifischen Geräteinformationen nutzt.
Voraussetzungen
Bevor Sie beginnen, stellen Sie sicher, dass Folgendes vorhanden ist:
- Visual Studio 2022 mit installierter Workload .NET MAUI
- Das NuGet-Paket Babel.Licensing (Version 11.0.0 oder höher)
- Eine laufende Instanz des Babel Licensing Service (lokal oder auf einem Server)
- Grundkenntnisse in der Entwicklung von .NET-MAUI-Anwendungen
- Eine Lizenz für Babel Licensing in der Edition Server oder Data Center
Beispielprojekt
Das vollständige Beispielprojekt können Sie mit dem folgenden Befehl von GitHub herunterladen:
git clone https://github.com/babelfornet/maui-licensed-app.gitDieses Repository enthält eine vollständig implementierte MAUI-Anwendung, in die Babel Licensing auf allen unterstützten Plattformen eingebunden ist.

Lizenzierte MAUI-Anwendung
Warum Lizenzaktivierung in MAUI?
Mit MAUI (Multi-platform App UI) erstellen Entwickler plattformübergreifende Anwendungen aus einer einzigen Codebasis. Bei der Lizenzierung müssen Sie jedoch die Besonderheiten jeder Plattform berücksichtigen. Die Lizenzaktivierung eignet sich besonders gut für MAUI-Anwendungen, und zwar aus diesen Gründen:
- Gerätespezifische Bindung: Lizenzen sind mit dem Gerät verknüpft, auf dem die Anwendung läuft. Das verhindert die unbefugte Nutzung auf mehreren Geräten.
- Offlinebetrieb: Nach der Aktivierung arbeiten Anwendungen ohne ständige Verbindung zum Server, was für mobile Anwendungen ideal ist.
- Plattformübergreifende Kompatibilität: Das Lizenzmodell funktioniert auf den verschiedenen Plattformen (Android, iOS, Windows, MacCatalyst) einheitlich.
Die Projektstruktur einrichten
Das Beispiel MauiLicApp zeigt einen gut gegliederten Ansatz, um Babel Licensing in einer MAUI-Anwendung zu implementieren:
MauiLicensedApp/
├── Licensing/ # Core licensing implementation
│ ├── BabelLicensingExtensions.cs
│ ├── ISystemInformation.cs
│ └── LicensingService.cs
├── Platforms/ # Platform-specific implementations
│ ├── Android/
│ ├── iOS/
│ ├── MacCatalyst/
│ └── Windows/
├── Reporting/ # Exception reporting functionality
│ └── BabelReportingExtensions.cs
└── MauiProgram.cs # Application initializationDiese Struktur trennt die Lizenzierung vom Rest Ihrer Anwendung und behält dort, wo es nötig ist, plattformspezifische Implementierungen bei.
Die Basisklasse SystemInformation implementieren
Den Kern des plattformübergreifenden Lizenzierungssystems bildet die abstrakte Klasse SystemInformationBase. Sie definiert eine plattformunabhängige Schnittstelle, um die für die Lizenzaktivierung nötigen Systeminformationen zu erfassen:
public abstract class SystemInformationBase : ISystemInformation
{
public abstract string DeviceId { get; }
public abstract string DeviceManufacturer { get; }
public abstract string DeviceModel { get; }
public abstract string OsVersion { get; }
// Additional system properties...
}Diese Klasse implementiert die Schnittstelle ISystemInformation von Babel Licensing. Das sichert die Kompatibilität mit dem Lizenzierungssystem und bietet zugleich eine einheitliche Abstraktion über alle Plattformen hinweg.
Plattformspezifische Systeminformationen
In einer MAUI-Anwendung sind plattformspezifische Implementierungen von SystemInformationBase aus mehreren wichtigen Gründen unverzichtbar:
- Unterschiede beim Hardwarezugriff: Jede Plattform hat eigene APIs und Methoden für den Zugriff auf Hardwareinformationen. Android verwendet zum Beispiel
Build.SERIALoderSettings.Secure.ANDROID_ID, iOS dagegenUIDevice.CurrentDevice.IdentifierForVendor. - Sicherheitsbeschränkungen: Mobile Plattformen haben unterschiedliche Sicherheitsmodelle, die den Zugriff auf bestimmte Systeminformationen beschränken. Plattformspezifische Implementierungen können mit diesen Beschränkungen angemessen umgehen.
- Eindeutige Kennungen: Wie sich zuverlässige, dauerhafte Gerätekennungen erzeugen lassen, ist je nach Plattform verschieden. Was unter Windows funktioniert, funktioniert unter iOS oder Android nicht.
- Verfügbarkeit von Funktionen: Manche Hardwareinformationen, die auf einer Plattform verfügbar sind, sind auf einer anderen nicht zugänglich und erfordern plattformspezifische Alternativen.
So sieht das in der Praxis für die einzelnen Plattformen aus:
Android-Implementierung
Die Android-Implementierung nutzt Android-spezifische APIs, um die Systeminformationen zu erfassen:
public class SystemInformation : SystemInformationBase
{
public override string DeviceId
{
get
{
try
{
return Settings.Secure.GetString(_context.ContentResolver,
Settings.Secure.AndroidId) ?? string.Empty;
}
catch (Exception)
{
return string.Empty;
}
}
}
public override string DeviceManufacturer => Build.Manufacturer ?? string.Empty;
// Other implementations...
}iOS-Implementierung
Die iOS-Implementierung verwendet iOS-spezifische APIs:
public class SystemInformation : SystemInformationBase
{
public override string DeviceId
{
get
{
try
{
return UIDevice.CurrentDevice?.IdentifierForVendor?.AsString() ?? string.Empty;
}
catch (Exception)
{
return string.Empty;
}
}
}
public override string DeviceManufacturer => "Apple";
// Other implementations...
}Windows-Implementierung
Die Windows-Implementierung verwendet Windows Management Instrumentation (WMI), um die Systeminformationen zu erfassen:
public class SystemInformation : SystemInformationBase
{
public override string SystemUuid
{
get
{
try
{
using var searcher = new ManagementObjectSearcher(
"SELECT UUID FROM Win32_ComputerSystemProduct");
foreach (var obj in searcher.Get())
{
return obj["UUID"]?.ToString() ?? string.Empty;
}
return string.Empty;
}
catch (Exception)
{
return string.Empty;
}
}
}
// Other implementations...
}Plattformspezifische Implementierungen registrieren
Jede Plattform muss ihre eigene Implementierung von SystemInformation beim Start der Anwendung registrieren. Das geschieht in der Regel im plattformspezifischen Einstiegspunkt:
Für Android (MainApplication.cs):
[Application]
public class MainApplication : MauiApplication
{
public MainApplication(IntPtr handle, JniHandleOwnership ownership)
: base(handle, ownership)
{
// Register the SystemInformation service for licensing
LicenseServices.Current.AddService(typeof(ISystemInformation),
new SystemInformation());
}
protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp();
}Für iOS (Program.cs):
public class Program
{
static void Main(string[] args)
{
// Register the SystemInformation service for licensing
LicenseServices.Current.AddService(typeof(ISystemInformation),
new SystemInformation());
UIApplication.Main(args, null, typeof(AppDelegate));
}
}Für Windows (App.xaml.cs):
public partial class App : MauiWinUIApplication
{
protected override void OnLaunched(LaunchActivatedEventArgs args)
{
// Register the SystemInformation service for licensing
LicenseServices.Current.AddService(typeof(ISystemInformation),
new SystemInformation());
base.OnLaunched(args);
}
}Babel Licensing in MAUI konfigurieren
Wenn die plattformspezifischen Implementierungen vorhanden sind, muss Babel Licensing für die MAUI-Anwendung konfiguriert werden. Das geschieht mit Erweiterungsmethoden, die sich in das Dependency-Injection-System von MAUI einfügen:
public static MauiAppBuilder UseBabelLicensing(
this MauiAppBuilder builder,
Action<BabelLicensingConfiguration>? configureClient = null)
{
// Register platform-specific system information service
builder.Services.AddSingleton<SystemInformationBase>(serviceProvider =>
{
return LicenseServices.Current.GetService(typeof(ISystemInformation))
as SystemInformationBase ??
throw new InvalidOperationException("SystemInformation service not registered.");
});
// Create the BabelLicensing configuration
var config = new BabelLicensingConfiguration {
// Set the default client ID
ClientId = AppInfo.Current.Name,
// Set the machine ID using system UUID and name
MachineId = new HardwareId(
HardwareComponents.SystemUuid |
HardwareComponents.SystemName).ToMachineKey(),
// Set the signature provider with public key for license verification
SignatureProvider = RSASignature.FromKeys("PUBLIC_KEY_HERE")
};
// Apply custom configuration
configureClient?.Invoke(config);
// Register services
builder.Services.AddSingleton<BabelLicensing>(/* ... */);
builder.Services.AddSingleton<BabelServiceLicenseProvider>(/* ... */);
return builder;
}Diese Erweiterungsmethode wird dann in MauiProgram.cs verwendet, um die Lizenzierungskonfiguration anzuwenden:
public static MauiApp CreateMauiApp()
{
// Configure BabelLicensing service URL
string babelHttpServiceUrl = "https://your-license-server:5455";
var builder = MauiApp.CreateBuilder();
builder
.UseMauiApp<App>()
.UseBabelLicensing(config => {
config.ServiceUrl = babelHttpServiceUrl;
})
.UseBabelReporting(config => {
config.ServiceUrl = babelHttpServiceUrl;
})
.ConfigureFonts(fonts => { /* ... */ });
// Register the LicensingService for dependency injection
builder.Services.AddSingleton<LicensingService>();
return builder.Build();
}Den LicensingService erstellen
Die Klasse LicensingService bietet eine vereinfachte Schnittstelle für die Lizenzierungsvorgänge in der gesamten Anwendung:
public class LicensingService
{
private readonly BabelLicensing _client;
private readonly BabelServiceLicenseProvider _licenseProvider;
public LicensingService(BabelLicensing client, BabelServiceLicenseProvider licenseProvider)
{
_client = client;
_licenseProvider = licenseProvider;
}
public BabelLicensing Client => _client;
public bool IsLicensed => BabelLicenseManager.IsLicensed(typeof(BabelLicensingExtensions));
public string? UserKey => _licenseProvider.UserKey;
public async Task ActivateLicenseAsync(string userKey)
{
await _client.ActivateLicenseAsync(userKey, typeof(BabelLicensingExtensions));
}
public async Task DeactivateLicenseAsync()
{
if (!string.IsNullOrEmpty(UserKey))
{
await _client.DeactivateLicenseAsync(UserKey);
}
}
public async Task<ILicense> ValidateLicenseAsync()
{
return await BabelLicenseManager.ValidateAsync(typeof(BabelLicensingExtensions));
}
}Dieser Dienst kapselt die API von Babel Licensing hinter einer einfachen, anwendungsspezifischen Schnittstelle. Er lässt sich in jede Seite und jedes ViewModel injizieren, die Lizenzierungsfunktionen benötigen.
Lizenzaktivierung in der Oberfläche implementieren
Wenn die Lizenzierungsinfrastruktur steht, können Sie die Lizenzaktivierung in Ihrer Oberfläche implementieren. Hier ein Beispiel aus MainPage.xaml.cs:
private async void OnActivateClicked(object sender, EventArgs e)
{
try
{
if (_licensingService.IsLicensed)
{
// If licensed, validate the license
var license = await _licensingService.ValidateLicenseAsync();
ActivateBtn.Text = $"License valid: {license.Id}";
// Show system information
await DisplayAlert("System Info",
$"Device: {_systemInfo.DeviceManufacturer} {_systemInfo.DeviceModel}\n" +
$"OS: {_systemInfo.OperatingSystem} {_systemInfo.OsVersion}\n" +
$"System: {_systemInfo.SystemName}\n" +
$"UUID: {_systemInfo.SystemUuid}",
"OK");
}
else
{
// If not licensed, prompt for activation
string userKey = await DisplayPromptAsync("License Activation",
"Enter your license key:",
accept: "Activate",
cancel: "Cancel");
if (!string.IsNullOrEmpty(userKey))
{
try
{
await _licensingService.ActivateLicenseAsync(userKey);
await DisplayAlert("Success", "License activated successfully!", "OK");
UpdateLicenseStatus();
}
catch (Exception ex)
{
await DisplayAlert("Activation Failed",
$"Could not activate license: {ex.Message}", "OK");
}
}
}
}
catch (Exception ex)
{
await DisplayAlert("Error", $"License operation failed: {ex.Message}", "OK");
}
}Mit dieser Implementierung geben Benutzer einen Lizenzschlüssel ein und aktivieren die Anwendung. Nach der Aktivierung ist die Lizenz an das Gerät gebunden und kann bei späteren Starts der Anwendung validiert werden.
Fehlerberichte hinzufügen
Babel Licensing unterstützt auch Fehlerberichte, die Sie mit der Klasse BabelReportingExtensions in Ihre MAUI-Anwendung einbinden:
public static void ReportUnhandledException(this Exception ex)
{
try
{
var task = Task.Run(async () =>
{
try
{
await ex.SendReportAsync();
}
catch (Exception innerEx)
{
Debug.WriteLine($"Failed to report exception: {innerEx.Message}");
}
});
task.Wait(TimeSpan.FromSeconds(5));
}
catch (Exception reportEx)
{
Debug.WriteLine($"Failed to report exception: {reportEx.Message}");
}
}Diese Funktion lässt sich in den Handlern der Anwendung für unbehandelte Ausnahmen registrieren:
// In App.xaml.cs
private void SetupExceptionHandling()
{
AppDomain.CurrentDomain.UnhandledException += (sender, args) =>
{
var ex = args.ExceptionObject as Exception;
ex?.ReportUnhandledException();
};
}
Fehlerbericht
Bewährte Vorgehensweisen für die Lizenzaktivierung in MAUI
Damit die Lizenzierung in Ihrer MAUI-Anwendung reibungslos abläuft:
- Fehlerbehandlung: Implementieren Sie eine umfassende Fehlerbehandlung für Netzwerk- und Lizenzierungsvorgänge, insbesondere bei mobilen Anwendungen, deren Verbindung zeitweise unterbrochen sein kann.
- Eingeschränkter Weiterbetrieb: Wenn die Lizenzvalidierung wegen Verbindungsproblemen fehlschlägt, bieten Sie eine Kulanzfrist oder einen eingeschränkten Funktionsumfang an, statt die Anwendung vollständig zu sperren.
- Rückmeldung in der Oberfläche: Zeigen Sie den Lizenzstatus in der Oberfläche klar an, sodass erkennbar ist, ob eine Lizenz aktiv, abgelaufen oder ungültig ist.
- Tests: Testen Sie Ihre Lizenzierungsimplementierung auf allen Zielplattformen, um ein einheitliches Verhalten auf allen Geräten sicherzustellen.
Fazit
Die Lizenzaktivierung in einer .NET-MAUI-Anwendung mit Babel Licensing erfordert ein planvolles Vorgehen, das die plattformspezifischen Unterschiede berücksichtigt und die Lizenzierung dennoch einheitlich hält. Mit einer plattformunabhängigen Abstraktion und plattformspezifischen Implementierungen erfassen Sie zuverlässig die Systeminformationen, die für eine sichere Lizenzaktivierung nötig sind.
Das Beispiel MauiLicApp zeigt eine umfassende Implementierung, die auf den Plattformen Android, iOS, Windows und MacCatalyst funktioniert. Wenn Sie diesem Muster und den bewährten Vorgehensweisen dieser Anleitung folgen, schützen Sie Ihre MAUI-Anwendungen wirksam mit einem robusten Lizenzierungssystem.
Dieser Ansatz stellt sicher, dass Ihre Anwendungen nur gemäß Ihren Lizenzbedingungen verwendet werden, und bietet berechtigten Benutzern zugleich auf allen unterstützten Plattformen eine reibungslose Nutzung.