Guide pour la création de packages d'installation logicielle embarquée sous Windows18-HD19

Lors de la première tentative de déploiement d'une application sur un équipement industriel, j'ai été confronté à une erreur « Accès refusé ». J'ai d'abord soupçonné une panne matérielle. C'est un collègue qui m'a signalé, de manière anodine, que le « EWF n'était pas désactivé ». Cette anecdote illustre bien que, dans le monde de l'embarqué, le système d'exploitation est un environnement qu'il faut maîtriser, pas un allié par défaut.

Le scénario abordé ici – créer un installeur pour un équipement industriel exécutant une version personnalisée de Windows – peut sembler pointu. Cependant, les développeurs de dispositifs médicaux, de bornes en libre-service ou de systèmes embarqués véhiculaires y seront confrontés tôt ou tard.

La cible est Windows18-HD19, une variante du système dont la documentation est rare et les permissions serrées. À l'inverse d'un Windows standard, sa philosophie de conception repose sur l'immuabilité. Une fois démarré, la partition système (C:) agit comme un volume en lecture seule ; toute modification est éphémère, réinitialisée au redémarrage.

Cette architecture garantit stabilité et sécurité, mais rend les méthodes d'installation traditionnelles caduques. Les popups UAC bloquent les installations silencieuses, l'enregistrement de services est soumis à la vérification de signature, et même la modification d'un fichier de configuration nécessite de « dégeler » la partition système.

La solution passe par une adaptation de notre approche. Trois compétences clés sont requises :

  • Interaction avec le filtre de protection en écriture (EWF)
  • Établir la confiance du système via la signature numérique
  • Injecter la configuration sans interaction utilisateur

Cet article détaille la construction, basée sur une expérience réelle, d'un package d'installation fonctionnel pour Windows18-HD19.

Caractéristiques déterminantes du système

Windows18-HD19 n'est pas une simple version allégée de Windows. Dérivé de Windows 10 IoT Enterprise LTSB et spécifiquement taillé pour la carte mère HD19, il n'est pas disponible publiquement ; son SDK est soumis à accord de confidentialité (NDA). Ses traits distinctifs sont :

  • Image système minimale d'environ 4.5 Go
  • Démarrage en moins de 15 secondes
  • EWF (Enhanced Write Filter) activé par défaut
  • Gestionnaire des tâches, éditeur de registre et panneau de configuration désactivés
  • Composants non essentiels (Edge, Cortana, OneDrive) supprimés
  • Secure Boot UEFI obligatoire, requérant une signature pour tous les exécutables et pilotes

L'exigence de signature est critique. Tout fichier .exe non signé sera bloqué avec le message « Impossible de vérifier l'éditeur ». De plus, les politiques de groupe figent les paramètres système comme l'UAC. Toute écriture dans des répertoires protégés comme C:\Program Files échoue tant que l'EWF est actif.

Choix de l'outil d'installation : Inno Setup plutôt que WiX

Pour ce type de projet, l'outil WiX Toolset, souvent privilégié pour sa conformité et sa génération de packages MSI, présente des limites. L'exécution via msiexec complique la personnalisation, empêche un contrôle direct de l'EWF et ne garantit pas une exécution totalement silencieuse.

Inno Setup se révèle plus adapté. Il génère un exécutable unique, supporte l'extension par des scripts Pascal, peut s'exécuter avec des privilèges élevés et offre une intégration aisée avec les outils système.

Exemple de script de base (modifié) :

[Setup]
AppName=MonAppEmbarquee
AppVersion=2.1.0
DefaultDirName={pf}\MonAppEmbarquee
OutputBaseFilename=Installateur_MonApp_WIN18HD19
Compression=lzma
SolidCompression=yes
PrivilegesRequired=admin
Uninstallable=no

[Files]
Source: "build\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs

[Run]
Filename: "{app}\gestion_service.exe"; Parameters: "/configurer /mode=calme"; \
    StatusMsg: "Enregistrement du service..."; \
    Flags: runhidden waituntilterminated

La logique essentielle réside dans la section [Code], qui pilote l'état du système :

function PrepareInstallation(): Boolean;
var
  CodeRetour: Integer;
begin
  // Vérifier l'environnement cible
  if GetWindowsVersion() <> $0A000000 then
  begin
    MsgBox('Cet installeur est destiné exclusivement à Windows18-HD19.', mbError, MB_OK);
    Result := False;
    Exit;
  end;

  // Valider les modifications en attente et désactiver l'EWF
  Exec('ewfmgr', 'C: -commitall', '', SW_HIDE, ewWaitUntilTerminated, CodeRetour);
  Log('EWF: Transactions validées sur la disque.');

  Exec('ewfmgr', 'C: -deactivate', '', SW_HIDE, ewWaitUntilTerminated, CodeRetour);
  if CodeRetour = 0 then
    Log('EWF: Protection en écriture désactivée.');

  Result := True;
end;

procedure TraiterEtape(Etape: TSetupStep);
var
  CodeRetour: Integer;
begin
  if Etape = ssPostInstall then
  begin
    // Réactiver l'EWF après l'écriture des fichiers
    Exec('ewfmgr', 'C: -activate', '', SW_HIDE, ewWaitUntilTerminated, CodeRetour);
    if CodeRetour = 0 then
      Log('EWF: Protection en écriture réactivée.');
  end;
end;

Dans PrepareInstallation(), le script : 1) valide la version du système, 2) force l'écriture des données EWF en attente, 3) désactive temporairement le filtre. La fonction TraiterEtape() le réactive une fois l'installation des fichiers terminée. Cette « décongélation » contrôlée permet de modifier le volume système de manière sûre.

Note : La commande ewfmgr est spécifique à Windows Embedded. Si elle est introuvable, le pack d'outils WEC doit être installé sur le système cible.

Signature numérique : une exigence fondamentale

La désactivation de l'EWF ne suffit pas. Le Secure Boot UEFI impose que chaque exécutable soit signé par une autorité de certification (CA) de confiance. Sans cela, l'exécution est bloquée par le système, indépendamment des privilèges.

Un certificat EV (Extended Validation) de signature de code est recommandé pour sa confiance accrue et sa compatibilité matérielle (via une clé USB token). L'intégration de la signature dans une chaîne d'intégration continue (CI/CD) est une bonne pratique. La commande suivante illustre l'opération (paramètres adaptés) :

signtool sign /fd SHA256 /tr http://timestamp.sectigo.com /td SHA256 /v \
    /n "Mon Entreprise" Installateur_MonApp_WIN18HD19.exe

Les paramètres clés sont : /fd pour l'algorithme de hachage, /tr et /td pour l'horodatage (essentiel pour la pérennité de la signature). La clé privée du certificat ne doit jamais être stockée en clair ; un module HSM (Hardware Security Module) ou un coffre-fort cloud comme Azure Key Vault est préconisé. Une surveillance de l'expiration des certificats est cruciale.

Injection de configuration sans interaction

Les équipements embarqués ne disposent souvent pas d'écran ni de périphériques d'entrée. La saisie manuelle des paramètres (adresse serveur, identifiant unique) lors de l'installation est impossible en production.

Une approche par découverte de fichier de configuration externe est utilisée. L'installeur scrute des emplacements prédéfinis pour un fichier (ex. : config.ini). S'il est trouvé, la configuration est chargée automatiquement et les étapes interactives sont ignorées.

const
  CHEMIN_CONFIG = 'config.ini';
  EMPLACEMENTS: array[0..2] of string = (
    '{srcexe}\..\' + CHEMIN_CONFIG,  // Répertoire parent de l'installeur
    '{tmp}\' + CHEMIN_CONFIG,         // Répertoire temporaire système
    'D:\Config\' + CHEMIN_CONFIG      // Zone de données persistante
  );

function LocaliserFichierConfig(): string;
var
  I: Integer;
  Chemin: string;
begin
  Result := '';
  for I := Low(EMPLACEMENTS) to High(EMPLACEMENTS) do
  begin
    Chemin := ExpandConstant(EMPLACEMENTS[I]);
    if FileExists(Chemin) then
    begin
      Result := Chemin;
      Break;
    end;
  end;
end;

procedure ChargerParametres(const Fichier: string);
var
  Valeur: string;
begin
  Valeur := GetIniString('Reseau', 'AdresseServeur', '', Fichier);
  if Valeur <> '' then
    WizardForm.ChampReseau.Text := Valeur;

  Valeur := GetIniString('Equipement', 'NumeroSerie', '', Fichier);
  if Valeur <> '' then
    WizardForm.ChampIdentification.Text := Valeur;
end;

Les formats INI, JSON ou YAML sont possibles, mais l'INI reste le plus léger pour des systèmes aux ressources contraintes.

Stratégie d'emplacement des fichiers

Une règle d'or consiste à ne jamais altérer le contenu du répertoire C:\Windows. Outre la protection par l'EWF, ce répertoire est soumis à la WRP (Windows Resource Protection), et toute modification peut compromettre la stabilité ou la supportabilité.

La séparation des emplacements est conseillée :

  • C:\Program Files\MonApp\ : Binaires de l'application (sous protection EWF)
  • D:\Data\MonApp\ : Données persistantes, journaux, configuration (hors EWF)
  • D:\Sauvegardes\ : Images système ou points de restauration

La partition D: doit être formatée en NTFS et exclue de la protection EWF. Ainsi, les mises à jour des binaires sur C: n'affectent pas la configuration sur D:, et les journaux survivent aux redémarrages.

Enregistrement automatique des services

Placer un raccourci dans le dossier de démarrage est inefficace, car ce dossier est sous protection EWF. La méthode correcte consiste à enregistrer l'application comme un service Windows.

sc create "MonServiceApp" binPath= "D:\Data\MonApp\HoteService.exe" start= auto obj= LocalSystem

L'exécutable du service doit lui-même être signé. Le principe du moindre privilège recommande d'utiliser un compte de service dédié à faibles privilèges plutôt que LocalSystem si possible.

Déploiement de masse via réseau PXE/MDT

Pour des centaines d'appareils, une solution manuelle est impraticable. Une infrastructure basée sur PXE et Microsoft Deployment Toolkit (MDT) permet un déploiement entièrement automatisé.

Le flux typique est :

  1. L'appareil démarre via PXE et se connecte au serveur MDT.
  2. Un environnement WinPE personnalisé est téléchargé et chargé en mémoire.
  3. L'image de base Windows18-HD19 est appliquée.
  4. Des scripts d'installation automatisent l'exécution du package et l'injection de la configuration.
  5. L'appareil redémarre sur son système opérationnel final.

Cette méthode, combinée à des outils comme WDS et SCCM, permet un suivi en temps réel, une gestion des échecs et une collecte centralisée des journaux d'installation.

Checklist de dépannage et optimisations

Des problèmes courants peuvent survenir :

  • « Accès refusé » durant l'installation : EWF non désactivé. Intégrer la désactivation dans le script.
  • Configuration perdue après redémarrage : Fichier écrit sur la partition C: au lieu de D:.
  • Service ne démarre pas : Exécutable non signé ou chemin contenant des espaces mal échappés.
  • Échec de mise à jour OTA : Conflit de version. Implémenter une procédure de nettoyage des anciens fichiers.

Des optimisations supplémentaires améliorent la fiabilité :

  • Durée de vie du SSD : Désactiver le fichier d'échange et l'hibernation. Diriger les journaux vers une RAM disk avec synchronisation périodique vers le disque.
  • Sécurité : Chiffrement TLS 1.3 pour toutes les communications, mots de passe robustes, audit régulier des journaux d'événements.
  • Maintenabilité : Activer l'accès distant (SSH, PowerShell Remoting) avec restrictions IP, offrir une API REST pour le monitoring, prévoir une restauration système par clé GPIO.

Cette méthodologie a permis, dans un projet réel de terminaux d'acquisition d'images médicales, de réduire le temps de déploiement par appareil de 45 à 8 minutes, et le taux d'échec d'installation de 12% à 0.3%. Elle assure une gestion uniforme des versions, des mises à jour à distance et une récupération rapide en cas de panne, transformant une contrainte technique en fiabilité opérationnelle.

Étiquettes: Windows Embedded Inno Setup Enhanced Write Filter Code Signing PXE Deployment

Publié le 5 juin à 19h39