C# et .NET sont la cible la plus naturelle pour une application WinDev de gestion : même culture d'application Windows et de données structurées, mais une plateforme ouverte, très répandue et maintenue sur le long terme. Voici comment nous passons du WLangage au C# sans perdre vos règles métier.
Une application WinDev concentre souvent des années de règles de gestion : calculs de prix, contrôles de saisie, enchaînements de traitements, éditions. Le problème n'est pas ce qu'elle fait, mais ce sur quoi elle repose : un atelier de développement propriétaire, un langage que peu de développeurs pratiquent, des licences à renouveler et des choix techniques qui appartiennent à l'éditeur.
.NET répond à ces trois points. C'est une plateforme open source, utilisée par un très grand nombre d'entreprises, pour laquelle il est facile de recruter ou de trouver un prestataire. Le C# est un langage typé, outillé et documenté, avec des environnements de développement gratuits ou largement diffusés. Et surtout, .NET couvre tous les usages d'une application WinDev :
Le C# n'est pas la seule cible possible : Node.js ou une stack entièrement web peuvent mieux convenir à certains projets. Nous vous recommandons une technologie selon votre contexte, jamais par habitude. Mais pour une équipe qui pense « application de gestion », c'est souvent la transition la plus douce.
La première étape d'une migration consiste à faire correspondre chaque brique du projet WinDev à son équivalent dans le monde .NET. Ce tableau résume les correspondances que nous utilisons le plus souvent.
| Dans WinDev | En C# / .NET |
|---|---|
| Fenêtre (FEN_…) et ses champs | Fenêtre WPF ou formulaire WinForms, ou page web d'une application ASP.NET Core / React |
| Code des champs (clic, sortie, modification) | Gestionnaires d'événements, ou commandes d'un ViewModel (modèle MVVM) |
| Procédures globales et collections de procédures | Classes de services, injectées là où elles sont utilisées |
| Classes WLangage | Classes C# (héritage, interfaces, propriétés) |
| Analyse HFSQL (fichiers, rubriques, liaisons) | Schéma SQL et entités Entity Framework Core |
| Fonctions H* (HLitRecherche, HAjoute, HModifie…) | Requêtes LINQ ou SQL paramétré via EF Core ou Dapper |
| Requêtes de l'éditeur (REQ_…) | Requêtes LINQ, vues SQL ou requêtes SQL nommées |
| États et impressions | Génération de PDF et de documents avec une bibliothèque de reporting .NET |
| Variables globales du projet | Configuration (appsettings.json) et services à durée de vie contrôlée |
| ThreadExécute et traitements longs | async / await, Task, services d'arrière-plan |
| Groupware utilisateur | ASP.NET Core Identity, Active Directory ou fournisseur d'identité |
| Composants externes, DLL, ActiveX | Paquets NuGet, ou interopérabilité .NET le temps de les remplacer |
Ces équivalences ne sont pas des traductions mécaniques. Une fenêtre WinDev mélange souvent l'affichage, les contrôles de saisie et les accès à la base dans le même code. En .NET, on sépare ces responsabilités : l'écran affiche, un service applique la règle métier, une couche d'accès aux données lit et écrit. C'est ce découpage qui rendra votre logiciel testable et facile à faire évoluer.
Prenons une procédure typique : elle parcourt les commandes d'un client, totalise les montants et applique une remise au-delà d'un seuil. En WinDev, la lecture se fait enregistrement par enregistrement avec les fonctions HFSQL.
// Procédure globale CalculTotalClient
PROCÉDURE CalculTotalClient(nIDClient est un entier) : monétaire
moTotal est un monétaire = 0
HLitRecherchePremier(Commande, IDClient, nIDClient)
TANTQUE HTrouve(Commande)
moTotal += Commande.MontantHT
HLitSuivant(Commande, IDClient)
FIN
// Remise fidélité au-delà de 1 000 €
SI moTotal > 1000 ALORS
moTotal = moTotal * 0.95
FIN
RENVOYER moTotalEn C#, la même règle devient une méthode d'un service. Le total est calculé par la base de données en une seule requête, au lieu d'une boucle côté application, et les valeurs du seuil et du taux sont nommées au lieu d'être enfouies dans le code.
public class CommandeService(AppDbContext db)
{
private const decimal SeuilRemise = 1000m;
private const decimal TauxRemise = 0.05m;
// Règle métier reprise de CalculTotalClient (WinDev)
public async Task<decimal> CalculerTotalClientAsync(int idClient)
{
decimal total = await db.Commandes
.Where(c => c.IdClient == idClient)
.SumAsync(c => c.MontantHT);
return total > SeuilRemise ? total * (1 - TauxRemise) : total;
}
}La règle est désormais isolée, donc testable. Les comportements observés dans l'ancienne application deviennent des tests automatiques, qui garantissent que le nouveau code calcule exactement la même chose :
[Fact]
public async Task Remise_appliquee_au_dela_du_seuil()
{
var service = CreerServiceAvecCommandes(42, 600m, 500m);
decimal total = await service.CalculerTotalClientAsync(42);
Assert.Equal(1045m, total); // 1 100 € - 5 %
}Multipliez cet exemple par quelques centaines de procédures et vous obtenez l'essentiel d'une migration : comprendre ce que fait le code, l'exprimer proprement dans le nouveau langage et prouver que rien n'a changé pour l'utilisateur.
Le type monétaire de WinDev est un décimal à virgule fixe. Le reprendre en double introduit des écarts d'arrondi sur les montants. En C#, il faut utiliser decimal partout où l'on manipule de l'argent, et vérifier que les règles d'arrondi (au centime, à la ligne ou au total) sont identiques.
En WLangage, les tableaux et les positions dans une chaîne commencent à 1 : Milieu(sCode, 1, 3) renvoie les trois premiers caractères. En C#, tout commence à 0 : code.Substring(0, 3). C'est une source classique d'erreurs décalées d'un caractère, d'où l'intérêt des tests de non-régression.
Dans beaucoup de bases HFSQL, une date « vide » est une chaîne vide ou une valeur par défaut, pas une vraie valeur nulle. En C#, une date absente doit devenir un DateTime? (ou DateOnly?) nul. Il faut décider, champ par champ, comment ces valeurs sont converties. Le sujet est détaillé dans notre page HFSQL vers PostgreSQL.
Les boucles HLitRecherchePremier / HLitSuivant fonctionnent bien sur une base locale. Recopiées telles quelles sur un serveur SQL, elles multiplient les allers-retours et ralentissent l'application. On les remplace par des requêtes ensemblistes : filtrer, totaliser et trier dans la base, pas dans une boucle.
Une même règle peut se retrouver dans le clic d'un bouton, la sortie d'un champ et une procédure globale, avec de légères variantes. L'audit sert justement à repérer ces doublons, à choisir la version de référence et à la centraliser dans un service unique.
WinDev fait beaucoup de choses sans qu'on l'écrive : contexte HFSQL partagé, filtres actifs, blocages d'enregistrements, affichage automatique des tables. En .NET, ces comportements doivent être explicites : transactions, gestion de la concurrence, chargement des listes. Les oublier, c'est découvrir des écarts en production.
Votre application WinDev peut être maintenue pendant toute la durée de la migration : correctifs et évolutions urgentes continuent d'être traités sur l'existant.
À l'issue du projet, 100 % du code source vous est livré. Vous ne payez plus de redevance éditeur et vous restez libre de faire évoluer votre logiciel avec le prestataire de votre choix. Pour une vue d'ensemble de nos prestations, consultez notre page migration et refonte d'applications WinDev.
Pas de façon fiable. Les outils de conversion ligne à ligne reproduisent la structure de l'ancien code, y compris ses défauts, et butent sur tout ce qui dépend du framework WinDev (fonctions H*, champs, états). Nous analysons le code pour en extraire les règles métier, puis nous les réécrivons en C# idiomatique. L'IA peut accélérer cette lecture, si vous le souhaitez, mais chaque ligne est relue par un développeur.
Les deux sont possibles en .NET. Une application WPF ou WinForms reste pertinente pour des postes fixes très interactifs. Une application web ASP.NET Core avec un front React ou Angular simplifie le déploiement et ouvre l'accès à distance et au mobile. Le choix se fait pendant l'audit, selon vos utilisateurs et vos contraintes.
Pas forcément. Une nouvelle couche C# peut d'abord travailler avec les données existantes, puis la base est reprise vers PostgreSQL, MySQL / MariaDB ou SQL Server. L'ordre dépend du scénario de migration retenu : progressif ou complet.
Ils sont inventoriés pendant l'audit, puis recréés avec une solution de génération de documents du monde .NET. Les états les plus utilisés sont repris en priorité, et c'est souvent l'occasion de supprimer ceux qui ne servent plus.
Décrivez-nous votre projet en quelques mots. Nous revenons vers vous sous 48 h ouvrées.