Plug-ins WSL

Les applications Windows peuvent désormais créer et interagir avec des processus Linux s’exécutant au sein du Sous-système Windows pour Linux (WSL) avec des plug-ins WSL. Cet article donne une vue d’ensemble de leur fonctionnement et explique comment commencer à les utiliser.

Présentation des fonctionnalités des plug-ins

Les plug-ins WSL fournissent les principales fonctionnalités suivantes :

  • Permet aux applications de spécifier un exécutable Windows qui démarre quand la machine virtuelle WSL est démarrée
  • L’exécutable Windows peut créer des processus Linux au sein de WSL et peut communiquer directement avec eux en utilisant un socket virtualisé

En utilisant celles-ci, les applications Windows peuvent s’appuyer sur des expériences WSL et fournir des fonctionnalités supplémentaires liées au Sous-système Windows pour Linux.

Installation d’un plug-in

En tant que créateur de plug-in WSL, vous pouvez installer votre plug-in sur un ordinateur en définissant une clé de Registre pour la faire pointer vers le fichier DLL de votre plug-in.

En tant qu’utilisateur WSL, toute application que vous utilisez va installer automatiquement les plug-ins WSL dans le cadre de son processus d’installation normal.

Création de vos propres plug-ins

Pour démarrer un projet de plug-in, vous devez créer une DLL Win32. La façon la plus simple de s’y prendre est d’essayer notre projet d’exemple de plug-in WSL. Pour cela, clonez le dépôt d’exemples de plug-ins WSL dans un dossier local avec git clone, puis ouvrez-le dans Visual Studio.

Après avoir ouvert le projet, accédez au fichier dllmain.cpp (https://github.com/microsoft/wsl-plugin-sample/blob/main/plugin.cpp) et vous verrez la liste des fonctions disponibles pour les plug-ins WSL.

Vous pouvez ensuite cliquer sur l’onglet « Générer » et générer votre projet, ce qui va produire une DLL prête à être utilisée, probablement sous wsl-plugin-sample\x64\Debug\WSLPluginSample.dll.

Test de votre plug-in

Les plug-ins WSL vont s’exécuter seulement s’ils sont signés numériquement. Pour tester cela, vous devez activer la signature de test sur votre machine.

Activation de la signature de test et création d’une certification de test

Ouvrez une fenêtre PowerShell avec élévation de privilèges et activez la signature de test en exécutant cette commande :

## If this command results in "The value is protected by Secure Boot policy and cannot be modified or deleted"
## Then reboot the PC, go into BIOS settings, and disable Secure Boot. BitLocker may also affect your ability to modify this setting.
Bcdedit.exe -set TESTSIGNING ON

Une fois la signature de test activée (un redémarrage peut être nécessaire), dans une invite de commandes PowerShell avec élévation de privilèges qui se trouve dans le répertoire de votre fichier WSLPluginSample.dll créé ci-dessus, nous allons créer un certificat de test WSL :

# Create the cert
$certname = "WSLPluginTestCert"
$cert = New-SelfSignedCertificate -Subject "CN=$certname" -CertStoreLocation "Cert:\CurrentUser\My" -KeyExportPolicy Exportable -KeySpec Signature -KeyLength 2048 -KeyAlgorithm RSA -HashAlgorithm SHA256 -Type CodeSigningCert

# Export it to a local path
Export-Certificate -Cert $cert -FilePath ".\$certname.cer"

# Sign the DLL file
Set-AuthenticodeSignature -FilePath "C:\dev\Path\To\Your\WSLPlugin.dll" -Certificate $cert

Enfin, importez le certificat dans l’autorité de certification racine de confiance :

certutil -addstore "Root" ".\$certname.cer"

Pour plus d’informations, consultez Comment créer un certificat auto-signé.

Installation du plug-in

Dans la même fenêtre PowerShell avec élévation de privilèges, exécutez la commande ci-dessous pour installer le plug-in, en veillant à remplacer le chemin vers la DLL du plug-in par votre chemin existant :

Reg.exe add HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Lxss\Plugins /v demo-plugin /t REG_SZ /d C:\Path\to\plugin.dll  /f

Pour utiliser le plug-in, redémarrez le service wsl via :

sc.exe stop wslservice
wsl.exe echo “test”

Votre plug-in doit maintenant être chargé. Si le plug-in n’a pas pu être chargé, consultez la section Résolution des problèmes et informations supplémentaires pour plus d’informations.

Ensuite, quand vous avez terminé, vous pouvez exécuter cette commande pour supprimer le plug-in (n’oubliez pas que vous devrez redémarrer le service WSL pour qu’il prenne effet) :

Reg.exe delete HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Lxss\Plugins /v demo-plugin

Résolution des problèmes et informations supplémentaires

Codes d’erreur courants :

  • Wsl/Service/CreateInstance/CreateVm/Plugin/ERROR_MOD_NOT_FOUND –> la DLL du plug-in n’a pas pu être chargée. Vérifiez que le chemin d’inscription du plug-in est correct
  • Wsl/Service/CreateInstance/CreateVm/Plugin/TRUST_E_NOSIGNATURE –> la DLL du plug-in n’est pas signée ou sa signature n’est pas approuvée par l’ordinateur
  • Wsl/Service/CreateInstance/CreateVm/Plugin/* –> la DLL du plug-in a retourné une erreur dans WSLPLUGINAPI_ENTRYPOINTV1 ou OnVmStarted()
  • Wsl/Service/CreateInstance/Plugin/* –> la DLL du plug-in a retourné une erreur dans OnDistributionStarted()

Plug-ins Linux, espace utilisateur

Les processus Linux créés via ExecuteBinary() s’exécutent dans l’espace de noms racine de la machine virtuelle WSL2. Cet espace de noms n’est associé à aucune distribution et a un système de fichiers racine très minimal basé sur Mariner.

Ce système de fichiers est un tmpfs accessible en écriture, ce qui signifie que toutes les modifications apportées à celui-ci sont supprimées quand la machine virtuelle WSL2 est arrêtée.

Vous pouvez inspecter le contenu de l’espace de noms racine en exécutant wsl --debug-shell pendant que WSL s’exécute.

Considérations supplémentaires

  • Tous les hooks de plug-in WSL sont synchrones, ce qui signifie que WSL attend que les hooks de plug-in soient terminés avant de continuer.
  • Toute erreur retournée par un plug-in est considérée comme irrécupérable par WSL (ce qui signifie que la distribution de l’utilisateur ne va pas démarrer)
  • Le code du plug-in s’exécute dans le même espace d’adressage que le service WSL. Tout incident dans un plug-in bloque l’intégralité du service WSL, ce qui peut entraîner une perte de données