Activation de licence dans MAUI
Ce guide explique comment implémenter l’activation de licence dans une application .NET MAUI avec Babel Licensing. Cette approche vous permet de lier les licences à des appareils précis de manière sécurisée, afin que votre logiciel ne soit utilisé que conformément à vos conditions de licence. En suivant ce schéma d’implémentation, vous obtenez un système de gestion des licences robuste, qui fonctionne de façon cohérente sur plusieurs plateformes tout en exploitant les informations propres à l’appareil sur chacune d’elles.
Prérequis
Avant de commencer, assurez-vous de disposer des éléments suivants :
- Visual Studio 2022 avec la charge de travail .NET MAUI installée
- Le package NuGet Babel.Licensing (version 11.0.0 ou ultérieure)
- Une instance du Babel Licensing Service en cours d’exécution (en local ou sur un serveur)
- Des notions de base du développement d’applications .NET MAUI
- Une licence Babel Licensing en édition Server ou Data Center
Projet d’exemple
Vous pouvez télécharger le projet d’exemple complet depuis GitHub avec la commande suivante :
git clone https://github.com/babelfornet/maui-licensed-app.gitCe dépôt contient une application MAUI complète qui intègre Babel Licensing sur toutes les plateformes prises en charge.

Application MAUI sous licence
Pourquoi l’activation de licence dans MAUI ?
MAUI (Multi-platform App UI) permet aux développeurs de créer des applications multiplateformes à partir d’une seule base de code. Pour implémenter la gestion des licences, vous devez toutefois tenir compte des particularités de chaque plateforme. L’activation de licence convient particulièrement bien aux applications MAUI pour les raisons suivantes :
- Liaison à l’appareil : les licences sont liées à l’appareil sur lequel l’application s’exécute, ce qui empêche toute utilisation non autorisée sur plusieurs appareils.
- Fonctionnement hors ligne : une fois activées, les applications fonctionnent sans connexion permanente au serveur, ce qui convient bien aux applications mobiles.
- Compatibilité multiplateforme : la formule de licence fonctionne de façon cohérente sur les différentes plateformes (Android, iOS, Windows, MacCatalyst).
Mettre en place la structure du projet
L’exemple MauiLicApp présente une façon bien organisée d’implémenter Babel Licensing dans une application MAUI :
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 initializationCette structure sépare ce qui relève de la gestion des licences du reste de votre application, tout en conservant des implémentations propres à chaque plateforme là où elles sont nécessaires.
Implémenter la classe de base SystemInformation
Le cœur de ce système de gestion des licences multiplateforme est la classe abstraite SystemInformationBase, qui définit une interface indépendante de la plateforme pour collecter les informations système nécessaires à l’activation de licence :
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...
}Cette classe implémente l’interface ISystemInformation de Babel Licensing, ce qui garantit la compatibilité avec le système de gestion des licences tout en offrant une abstraction cohérente entre les plateformes.
Informations système propres à chaque plateforme
Dans une application MAUI, les implémentations de SystemInformationBase propres à chaque plateforme sont indispensables pour plusieurs raisons :
- Différences d’accès au matériel : chaque plateforme possède ses propres API et méthodes pour accéder aux informations matérielles. Par exemple, Android utilise
Build.SERIALouSettings.Secure.ANDROID_ID, tandis qu’iOS utiliseUIDevice.CurrentDevice.IdentifierForVendor. - Restrictions de sécurité : les plateformes mobiles ont des modèles de sécurité différents, qui restreignent l’accès à certaines informations système. Les implémentations propres à chaque plateforme permettent de composer correctement avec ces restrictions.
- Identifiants uniques : la façon de générer des identifiants d’appareil fiables et persistants varie selon la plateforme. Ce qui fonctionne sous Windows ne fonctionne pas sous iOS ou Android.
- Disponibilité des fonctionnalités : certaines informations matérielles disponibles sur une plateforme peuvent ne pas être accessibles sur une autre, ce qui impose des solutions de remplacement propres à chaque plateforme.
Voici comment cela se traduit en pratique sur les différentes plateformes :
Implémentation Android
L’implémentation Android s’appuie sur les API propres à Android pour collecter les informations système :
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...
}Implémentation iOS
L’implémentation iOS utilise les API propres à iOS :
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...
}Implémentation Windows
L’implémentation Windows utilise Windows Management Instrumentation (WMI) pour collecter les informations système :
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...
}Inscrire les implémentations propres à chaque plateforme
Chaque plateforme doit inscrire sa propre implémentation de SystemInformation au démarrage de l’application. Cette inscription se fait généralement dans le point d’entrée propre à la plateforme :
Pour 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();
}Pour 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));
}
}Pour 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);
}
}Configurer Babel Licensing dans MAUI
Une fois les implémentations propres à chaque plateforme en place, il faut configurer Babel Licensing pour l’application MAUI. Cette configuration repose sur des méthodes d’extension qui s’intègrent au système d’injection de dépendances de MAUI :
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;
}Cette méthode d’extension est ensuite utilisée dans MauiProgram.cs pour appliquer la configuration de la gestion des licences :
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();
}Créer le LicensingService
La classe LicensingService fournit une interface simplifiée pour les opérations de gestion des licences dans toute votre application :
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));
}
}Ce service encapsule l’API de Babel Licensing derrière une interface simple et propre à l’application. Il peut être injecté dans toute page ou tout modèle de vue qui a besoin des fonctionnalités de gestion des licences.
Implémenter l’activation de licence dans l’interface utilisateur
Une fois l’infrastructure de gestion des licences en place, vous pouvez implémenter l’activation de licence dans votre interface utilisateur. Voici un exemple tiré de 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");
}
}Cette implémentation permet aux utilisateurs de saisir une clé de licence et d’activer l’application. Une fois activée, la licence est liée à l’appareil et peut être validée aux lancements suivants de l’application.
Ajouter les rapports d’exception
Babel Licensing prend aussi en charge les rapports d’exception, que vous pouvez intégrer à votre application MAUI avec la classe BabelReportingExtensions :
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}");
}
}Cette fonctionnalité peut être inscrite dans les gestionnaires d’exceptions non gérées de l’application :
// In App.xaml.cs
private void SetupExceptionHandling()
{
AppDomain.CurrentDomain.UnhandledException += (sender, args) =>
{
var ex = args.ExceptionObject as Exception;
ex?.ReportUnhandledException();
};
}
Rapport d’exception
Bonnes pratiques pour l’activation de licence dans MAUI
Pour que la gestion des licences se déroule sans accroc dans votre application MAUI :
- Gestion des erreurs : implémentez une gestion complète des erreurs pour les opérations réseau et de gestion des licences, en particulier pour les applications mobiles dont la connectivité peut être intermittente.
- Dégradation progressive : lorsque la validation de licence échoue à cause de problèmes de connectivité, prévoyez une période de grâce ou des fonctionnalités limitées plutôt que de bloquer complètement l’application.
- Retour dans l’interface utilisateur : indiquez clairement l’état de la licence dans l’interface utilisateur, pour qu’il soit évident qu’une licence est active, expirée ou non valide.
- Tests : testez votre implémentation de la gestion des licences sur toutes les plateformes cibles pour garantir un comportement cohérent d’un appareil à l’autre.
Conclusion
Implémenter l’activation de licence dans une application .NET MAUI avec Babel Licensing demande une approche réfléchie, qui traite les différences entre les plateformes tout en préservant une gestion des licences cohérente. En créant une abstraction indépendante de la plateforme, assortie d’implémentations propres à chacune, vous collectez de manière fiable les informations système nécessaires à une activation de licence sécurisée.
L’exemple MauiLicApp présente une implémentation complète qui fonctionne sur les plateformes Android, iOS, Windows et MacCatalyst. En suivant ce schéma et les bonnes pratiques décrites dans ce guide, vous protégez efficacement vos applications MAUI avec un système de gestion des licences robuste.
Cette approche garantit que vos applications ne sont utilisées que conformément à vos conditions de licence, sans gêner les utilisateurs légitimes sur l’ensemble des plateformes prises en charge.