SQL Server 2022 + ODBC 18 : corriger les crashs sans installer Visual Studio (C#/.NET)

Après migration vers SQL Server 2022 et l’ODBC Driver 18, votre appli C#/.NET plante sur une machine « propre », alors que l’installation de Visual Studio 2022 la stabilise. Voici comment reproduire la « magie » de Visual Studio en n’installant que les composants réellement nécessaires.

Sommaire

Problématique

Une application C#/.NET qui fonctionnait parfaitement avec SQL Server 2019 se met à planter après passage à SQL Server 2022 et à l’ODBC Driver 18 for SQL Server sur une VM neuve (aucun outil développeur). L’installation de Visual Studio 2022 fait disparaître les plantages — mais Visual Studio ne doit pas être présent en production. L’enjeu est d’identifier les dépendances installées par Visual Studio (runtimes et bibliothèques partagées) et de les intégrer au poste cible sans déployer l’éditeur.

Pourquoi « Visual Studio répare » une application qui plante ?

Visual Studio 2022 installe ou déclenche l’installation de composants de runtime dont dépend votre application, directement ou via le pilote ODBC 18 :

  • Microsoft Visual C++ Redistributable 2015–2022 (v14.x) (x86 et x64) — indispensables car msodbcsql18.dll et de nombreuses DLL natives s’appuient sur vcruntime140*.dll, msvcp140*.dll, concrt140.dll, etc.
  • Runtimes .NET : .NET Framework 4.8 (si appli .NET Fx), .NET Desktop Runtime / ASP.NET Core Runtime (si appli .NET 6/7/8 non « self‑contained »).
  • Certificats racines et composants SChannel/TLS mis à jour via Windows Update.
  • Éventuellement d’autres composants partagés (MSBuild, SDK .NET, outils de débogage), non requis en production.

Constats et causes possibles

ObservationExplication la plus probable
Visual Studio rend l’application stableInstallation des Microsoft Visual C++ Runtime 14.x et de composants partagés (.NET Runtime/SDK, MSBuild, DLL MFC/ATL) consommés implicitement par l’application ou par les pilotes.
Passage à SQL Server 2022SQL Server Native Client (SQLNCLI/SQLNCLI11) est retiré et obsolète ; toute référence à ce fournisseur doit être supprimée.
Utilisation d’ODBC Driver 18Le pilote force Encrypt=yes par défaut ; un certificat serveur invalide, l’absence de TrustServerCertificate=yes en test ou un TLS 1.2 mal configuré provoquent des erreurs fatales.
Comportement identique sur Windows 10 et 11La panne est liée à une dépendance logicielle manquante (runtime/bibliothèques), pas à une build particulière de l’OS.

Plan d’action rapide (TL;DR)

  1. Installer Visual C++ Redistributable 2015–2022 v14.x en x64 et x86.
  2. Vérifier/installer le .NET Runtime requis ou publier l’appli en self‑contained.
  3. Mettre à jour vers ODBC Driver 18 (même bitness que l’appli) et Microsoft.Data.SqlClient ≥ 5.x pour ADO.NET.
  4. Corriger la chaîne de connexion : Encrypt=yes + TrustServerCertificate=yes (uniquement si aucun certificat valide n’est encore déployé).
  5. Retirer toute référence à SQLNCLI/SQLNCLI11 et aux composants SNAC obsolètes.

Étapes détaillées et procédures

1) Inventorier ce qui manque sur la VM « propre »

Vérifier les VC++ 14.x (x86/x64) via le Registre :

# VC++ 2015-2022 - x64
Get-ItemProperty 'HKLM:\SOFTWARE\Microsoft\VisualStudio\14.0\VC\Runtimes\x64' `
| Select-Object Installed, Version

# VC++ 2015-2022 - x86

Get-ItemProperty 'HKLM:\SOFTWARE\Microsoft\VisualStudio\14.0\VC\Runtimes\x86' `
| Select-Object Installed, Version 

Contrôler l’ODBC Driver 18 (64 bits et 32 bits) :

# 64-bit
Get-ItemProperty 'HKLM:\SOFTWARE\ODBC\ODBCINST.INI\ODBC Driver 18 for SQL Server' `
| Select-Object Driver, Version

# 32-bit

Get-ItemProperty 'HKLM:\SOFTWARE\WOW6432Node\ODBC\ODBCINST.INI\ODBC Driver 18 for SQL Server' `
| Select-Object Driver, Version 

Confirmer le runtime .NET requis :

  • Appli .NET Framework : vérifier que .NET 4.8 est présent (HKLM:\SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full, Release ≥ 528040).
  • Appli .NET 6/7/8 framework‑dependent : lister les runtimes installés : dotnet --list-runtimes.
  • Si vous publiez en self‑contained, aucun runtime .NET n’est nécessaire sur la machine.

2) Installer uniquement les redistribuables requis

Visual C++ 2015–2022 Redistributable (correspond à VS 2022) :

  • Déployer VC_redist.x64.exe et VC_redist.x86.exe (les deux, même si votre appli est x64 : certaines dépendances tierces peuvent être x86).
  • Déploiement silencieux : VC_redist.x64.exe /quiet /norestart puis VC_redist.x86.exe /quiet /norestart.

.NET :

  • Pour .NET Framework : assurez-vous d’avoir la 4.8 (ou 4.8.1) activée via « Activer ou désactiver des fonctionnalités Windows ».
  • Pour .NET 6/7/8 : préférez publier l’application en self‑contained afin de ne plus dépendre d’un runtime global.

3) Mettre à jour les bibliothèques d’accès aux données

ODBC natif : utilisez ODBC Driver 18 for SQL Server (même bitness que votre exécutable). Évitez les pilotes hérités.

ADO.NET : remplacez System.Data.SqlClient par Microsoft.Data.SqlClient ≥ 5.x (compatibilité SQL Server 2022, Always Encrypted v2/TDS 8 côté serveur). Exemple NuGet :

dotnet add package Microsoft.Data.SqlClient --version 5.*

Exemple C# :

using Microsoft.Data.SqlClient;

var csb = new SqlConnectionStringBuilder {
DataSource = "tcp:MonServeur,1433",
Encrypt = true,
TrustServerCertificate = true, // en test seulement ! remplacé ensuite par un certificat valide
InitialCatalog = "MaBase",
UserID = "app_user",
Password = "********"
};
using var cn = new SqlConnection(csb.ConnectionString);
await cn.OpenAsync(); </code></pre>

<h3>4) Corriger la chaîne de connexion et la sécurité TLS</h3>
<p>Chaîne ODBC type&nbsp;:</p>
<pre><code class="language-ini">Driver={ODBC Driver 18 for SQL Server};
Server=tcp:MonServeur,1433;
Database=MaBase;
Encrypt=yes;
TrustServerCertificate=yes;  ; &lt;-- à utiliser UNIQUEMENT si vous n'avez pas encore de certificat serveur valide
UID=app_user;PWD=********;
</code></pre>
<ul>
  <li><strong>Retirez toute mention</strong> à <code>SQLNCLI</code>/<code>SQLNCLI11</code> (<em>SNAC</em>).</li>
  <li>En production, remplacez <code>TrustServerCertificate=yes</code> par un <strong>certificat serveur valide</strong> (CN/SAN correspondant au nom dans <code>Server=</code>).</li>
  <li>Installez le certificat dans <em>Ordinateur local &gt; Personnel &gt; Certificats</em>. Importez la chaîne complète (intermédiaires + racine si privée).</li>
</ul>
<p><strong>Activer/valider TLS&nbsp;1.2</strong> si environnement ancien ou durci&nbsp;:</p>
<pre><code class="language-cmd">REM Client TLS 1.2
reg add "HKLM\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2\Client" /v Enabled /t REG_DWORD /d 1 /f
reg add "HKLM\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2\Client" /v DisabledByDefault /t REG_DWORD /d 0 /f

REM Serveur TLS 1.2 (si SQL Server local)
reg add "HKLM\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2\Server" /v Enabled /t REG_DWORD /d 1 /f
reg add "HKLM\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2\Server" /v DisabledByDefault /t REG_DWORD /d 0 /f </code></pre>

<h3>5) Nettoyer les références héritées (SNAC, SQLOLEDB, SSDT)</h3>
<ul>
  <li>Recherchez dans vos sources et fichiers <code>.config</code> toute occurrence de <code>SQLNCLI</code>, <code>SQLNCLI11</code>, <code>SQLOLEDB</code> et supprimez‑la.</li>
  <li>Vérifiez vos packages NuGet&nbsp;: évitez les dépendances vers des wrappers OLE&nbsp;DB/ODBC obsolètes.</li>
  <li>Si vous êtes encore en OLE&nbsp;DB natif côté COM&nbsp;: utilisez <strong>Microsoft OLE&nbsp;DB Driver&nbsp;19 for SQL Server</strong> plutôt que <em>SQLOLEDB</em>.</li>
</ul>

<h3>6) Aligner l’architecture (x86/x64) et l’ODBC&nbsp;Admin</h3>
<table>
  <thead>
    <tr>
      <th>Élément</th>
      <th>64&nbsp;bits</th>
      <th>32&nbsp;bits</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>ODBC&nbsp;Administrator</td>
      <td><code>C:\Windows\System32\odbcad32.exe</code></td>
      <td><code>C:\Windows\SysWOW64\odbcad32.exe</code></td>
    </tr>
    <tr>
      <td>Pilote ODBC</td>
      <td>ODBC Driver&nbsp;18 (x64)</td>
      <td>ODBC Driver&nbsp;18 (x86)</td>
    </tr>
    <tr>
      <td>Build de l’appli</td>
      <td><code>AnyCPU</code> avec <code>Prefer32Bit=false</code> ou <code>x64</code></td>
      <td><code>x86</code></td>
    </tr>
  </tbody>
</table>
<p>Un exécutable x86 ne peut pas utiliser un pilote ODBC x64, et inversement. Soyez cohérent.</p>

<h3>7) Publier en «&nbsp;self‑contained&nbsp;» pour supprimer la dépendance au runtime global</h3>
<p>Commandes typiques&nbsp;:</p>
<pre><code class="language-powershell"># .NET 6/7/8
dotnet publish -c Release -r win-x64 --self-contained true -p:PublishSingleFile=true -p:PublishTrimmed=false
</code></pre>
<p>Extrait <code>.csproj</code>&nbsp;:</p>
<pre><code class="language-xml">&lt;PropertyGroup&gt;
  &lt;RuntimeIdentifier&gt;win-x64&lt;/RuntimeIdentifier&gt;
  &lt;SelfContained&gt;true&lt;/SelfContained&gt;
  &lt;PublishSingleFile&gt;true&lt;/PublishSingleFile&gt;
  &lt;PublishReadyToRun&gt;true&lt;/PublishReadyToRun&gt;
&lt;/PropertyGroup&gt;
</code></pre>
<p>Avantages&nbsp;: zèro dépendance au runtime .NET machine, déploiement plus prévisible. Attention&nbsp;: taille du binaire plus élevée.</p>

<h3>8) Activer le logging et obtenir un dump exploitable</h3>
<ul>
  <li><strong>ODBC Tracing</strong>&nbsp;: lancez <code>odbcad32.exe</code> &gt; onglet <em>Tracing</em> &gt; <em>Start Tracing Now</em>. Arrêtez après reproduction pour collecter le fichier <code>SQL.LOG</code>.</li>
  <li><strong>.NET</strong>&nbsp;: côté <em>Microsoft.Data.SqlClient</em>, activez l’EventSource&nbsp;:
    <pre><code class="language-csharp">AppContext.SetSwitch("Microsoft.Data.SqlClient.EnableActivitySource", true);
</code></pre>
  </li>
  <li><strong>WER LocalDumps</strong> (dump automatique en cas de crash)&nbsp;:
    <pre><code class="language-cmd">reg add "HKLM\SOFTWARE\Microsoft\Windows\Windows Error Reporting\LocalDumps\MonAppli.exe" /v DumpFolder /t REG_EXPAND_SZ /d "C:\Dumps" /f
reg add "HKLM\SOFTWARE\Microsoft\Windows\Windows Error Reporting\LocalDumps\MonAppli.exe" /v DumpType /t REG_DWORD /d 2 /f

Observateur d’événements : Journaux Windows > Application (erreurs .NET Runtime), Applications and Services Logs > Microsoft > Windows > Schannel (négociation TLS), et ODBC si activé.

9) Procédure de test sur VM « clean »

  1. Déployer l’appli publiée en self‑contained (ou installer le runtime .NET requis).
  2. Installer VC++ 14.x (x86 et x64).
  3. Installer ODBC Driver 18 (bitness alignée).
  4. Configurer la chaîne de connexion : Encrypt=yes + TrustServerCertificate=yes (temporaire) ou déployer le certificat serveur.
  5. Lancer l’appli : si ok, vous avez isolé les dépendances « transportées » par Visual Studio.

Tableau de correspondance « Symptômes → Remèdes »

SymptômeCause fréquenteRemède ciblé
vcruntime140.dll / msvcp140.dll manquantVC++ 14.x non installéInstaller les VC_redist x64 + x86
« SSL Provider: certificate chain not trusted »Pas de certificat serveur valideDéployer certificat serveur + chaîne complète OU TrustServerCertificate=yes (test seulement)
« Provider=SQLNCLI11… » / Keyword not supportedRéférence à SQL Native Client obsolèteRemplacer par ODBC 18 ou Microsoft.Data.SqlClient
ODBC Driver not foundBitness ou pilote absentInstaller ODBC 18 correspondant (x86/x64) et utiliser le bon odbcad32.exe
Crash silencieux au démarrageDLL native manquante (VC++), exception TLS non interceptéeInstaller VC++ 14.x, activer WER LocalDumps + ODBC Tracing pour confirmer

Bonnes pratiques de packaging/déploiement

  • Inclure un prérequis VC++ dans votre installeur (MSI/Setup/MDM) et vérification préalable (registre) pour éviter les surprises.
  • Éviter les dépendances globales : binaire .NET self‑contained, et si possible isoler les DLL natives (app local deployment) autorisées par la licence.
  • Standardiser les chaînes de connexion (ODBC/ADO.NET) dans des templates de configuration par environnement (Dev/Int/Prod) avec chiffrement activé par défaut.
  • Surveiller les changements de politique chiffrage (chiffrement par défaut côté pilote, versions de protocole) dans vos notes de version internes.

Exemples prêts à copier

Chaîne de connexion ODBC (test contrôlé)

Driver={ODBC Driver 18 for SQL Server};
Server=tcp:sql-prod.example.local,1433;
Database=ERP;
Encrypt=yes;
TrustServerCertificate=yes;   ; &lt;-- temporaire en préproduction
UID=erp_svc;PWD=********;
Connection Timeout=15;

Chaîne de connexion ADO.NET (production, avec certificat)

Server=tcp:sql-prod.example.local,1433;
Database=ERP;
Encrypt=yes;
TrustServerCertificate=no;
User ID=erp_svc;Password=********;

Détection automatique des prérequis (PowerShell)

$errors = @()

# VC++ x64/x86

$vcx64 = Get-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\VisualStudio\14.0\VC\Runtimes\x64' -ErrorAction SilentlyContinue
$vcx86 = Get-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\VisualStudio\14.0\VC\Runtimes\x86' -ErrorAction SilentlyContinue
if(-not $vcx64 -or $vcx64.Installed -ne 1){ $errors += 'VC++ 2015-2022 x64 manquant' }
if(-not $vcx86 -or $vcx86.Installed -ne 1){ $errors += 'VC++ 2015-2022 x86 manquant' }

# ODBC Driver 18 (x64)

$odbc18x64 = Get-ItemProperty -Path 'HKLM:\SOFTWARE\ODBC\ODBCINST.INI\ODBC Driver 18 for SQL Server' -ErrorAction SilentlyContinue
if(-not $odbc18x64){ $errors += 'ODBC Driver 18 x64 manquant' }

# .NET Framework 4.8

$fx = Get-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full' -ErrorAction SilentlyContinue
if(-not $fx -or $fx.Release -lt 528040){ $errors += '.NET Framework 4.8 absent' }

if($errors.Count -eq 0){ 'OK: tous les prérequis semblent présents.' } else { 'À corriger: ' + ($errors -join '; ') } 

FAQ de terrain

Faut‑il installer « Build Tools for Visual Studio 2022 » ?
Non pour l’exécution. En production, limitez‑vous aux Visual C++ Redistributable 14.x, au runtime .NET (si non self‑contained) et au pilote ODBC 18.

Pourquoi installer les redists en x86 et x64 ?
Parce que des DLL tierces ou des composants COM peuvent être 32 bits même si votre binaire principal est 64 bits. Installer les deux évite des plantages « à froid » difficilement traçables.

Mon appli .NET Framework utilisait System.Data.SqlClient. Dois‑je migrer ?
Recommandé. Microsoft.Data.SqlClient est la branche maintenue et supporte mieux SQL Server 2022. La migration est souvent drop‑in (namespace à changer, quelques options de connexion à adapter).

Le pilote ODBC 18 impose Encrypt=yes. Puis‑je le désactiver ?
Techniquement oui (Encrypt=no), mais déconseillé. Mieux vaut déployer un certificat serveur valide (ou utiliser TrustServerCertificate=yes à titre temporaire en pré‑prod) et conserver Encrypt=yes.

ODBC 18 x64 est installé mais mon appli ne le « voit » pas.
Vérifiez la bitness de l’appli : un exécutable x86 a besoin du pilote x86, visible uniquement depuis SysWOW64\odbcad32.exe.

Checklist finale de validation

  • VC++ 2015–2022 x86 et x64 installés (Registre : ...VC\Runtimes\... avec Installed=1).
  • ODBC Driver 18 installé (x86/x64) et référencé par la chaîne de connexion ou par la DSN.
  • .NET Runtime présent ou application publiée en self‑contained.
  • Encrypt=yes actif ; TrustServerCertificate=yes uniquement temporaire en non‑prod ; certificat serveur valide en prod.
  • ✅ Aucune référence restante à SQLNCLI/SQLNCLI11/SQLOLEDB.
  • ✅ Architecture cohérente (appli vs pilote) et ODBC Admin utilisé dans la bonne bitness.
  • ✅ Journaux/trace ODBC testés ; absence d’erreurs Schannel dans l’Observateur d’événements.

Résumé exécutable

Pour rétablir la stabilité sans Visual Studio : installez VC++ 14.x (x86/x64), le runtime .NET requis (ou publiez en self‑contained), déployez le pilote ODBC 18 aligné sur la bitness, activez le chiffrement correctement (certificat serveur valide), retirez SNAC et migrez vers Microsoft.Data.SqlClient côté ADO.NET. Testez sur une VM propre avec ODBC Tracing/WER pour valider qu’aucune DLL ou exception TLS ne reste en suspens. Ainsi, vous reproduisez exactement ce que « Visual Studio apportait » — mais sans l’éditeur —, avec un environnement de production minimal, sécurisé et pérenne.

Annexes

Registres utiles (lecture seule)

  • HKLM\SOFTWARE\Microsoft\VisualStudio\14.0\VC\Runtimes\{x86|x64} — Visual C++ 14.x
  • HKLM\SOFTWARE\ODBC\ODBCINST.INI\ODBC Driver 18 for SQL Server — pilote ODBC 18 (x64)
  • HKLM\SOFTWARE\WOW6432Node\ODBC\ODBCINST.INI\ODBC Driver 18 for SQL Server — pilote ODBC 18 (x86)
  • HKLM\SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full — .NET Framework 4.x
  • HKLM\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2\{Client|Server} — état de TLS 1.2

Ce qu’il ne faut plus utiliser

  • SQL Server Native Client : SQLNCLI/SQLNCLI11 (obsolètes).
  • SQLOLEDB (OLE DB historique) : préférez le Microsoft OLE DB Driver 19 si vous êtes en COM/OLE DB.
  • Dépendances implicites à Visual Studio (SDK, MSBuild) pour l’exécution : elles n’ont pas à être présentes en production.

Modèle de communication de changement (extrait)

« À compter de la version <X.Y.Z>, l’application utilise l’ODBC Driver 18 avec chiffrement activé par défaut. Les environnements production devront disposer d’un certificat serveur valide correspondant au nom DNS fourni dans la chaîne de connexion. Les prérequis suivants doivent être installés : Visual C++ Redistributable 2015–2022 (x64 et x86), ODBC Driver 18 (même bitness que l’application) et, selon le mode de publication, le runtime .NET adéquat. »


En appliquant ces étapes, vous obtenez un environnement de production minimal : fiable (plus de crashs liés aux runtimes manquants), sécurisé (TLS actif avec certificats corrects) et durable (sans composants de développement inutiles). Le comportement observé — « Visual Studio fait disparaître les erreurs » — n’était que la conséquence de runtimes implicitement fournis ; vous les maîtrisez désormais explicitement.

Sommaire