Simple Pinger w/ SQL Server Compact — Step-by-Step Tutorial

Simple Pinger with SQL Server Compact: Quick Setup Guide

Date: February 4, 2026

This guide shows a minimal, practical way to build a simple network pinger that records results into SQL Server Compact (SQL CE). It includes the project structure, code examples (C#), and steps to create the database, run ICMP pings, and store results. Assumes .NET (Framework or .NET Core/5+) and SQL Server Compact 4.0 (or compatible) are available.

What you’ll build

A small console app that:

  • Sends an ICMP ping to a list of hosts.
  • Records timestamp, host, round-trip time (ms), and success/failure into a SQL Server Compact database.
  • Can be run manually or scheduled.

Prerequisites

  • Windows (SQL Server Compact is Windows-focused).
  • .NET SDK (Framework 4.6.1+ or .NET ⁄7).
  • SQL Server Compact 4.0 x86/x64 installed or the local DLLs included.
  • Visual Studio or a code editor.

Project setup

  1. Create a new Console App (C#).
  2. Add references:
    • System.Data.SqlServerCe (if using installed SQL CE) or include SQL Server Compact runtime DLLs.
    • System.Net.NetworkInformation (for Ping).
  3. Create a folder for database file (e.g., AppData) and plan for file name: PingResults.sdf.

Database: create table

Use the following SQL to create the table (run via SQL CE tool or programmatically):

CREATE TABLE PingResults ( Id INT IDENTITY(1,1) PRIMARY KEY, Host NVARCHAR(255) NOT NULL, Timestamp DATETIME NOT NULL, Success BIT NOT NULL, RoundTripMs INT NULL, ErrorMessage NVARCHAR(1000) NULL );

(If running programmatically, see example below.)

Connection string

Use a file-based connection string pointing to the .sdf file:

Data Source=|DataDirectory|\PingResults.sdf; Persist Security Info=False;

If the database file doesn’t exist, create it programmatically using SqlCeEngine.

Code: simple pinger (C#)

csharp

using System; using System.Data; using System.Data.SqlServerCe; using System.Net.NetworkInformation; using System.IO; class SimplePinger { static string DbPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, “App_Data”, “PingResults.sdf”); static string ConnStr = \("Data Source=</span><span class="token interpolation-string interpolation" style="color: rgb(57, 58, 52);">{</span><span class="token interpolation-string interpolation expression language-csharp">DbPath</span><span class="token interpolation-string interpolation" style="color: rgb(57, 58, 52);">}</span><span class="token interpolation-string" style="color: rgb(163, 21, 21);">; Persist Security Info=False;"</span><span class="token" style="color: rgb(57, 58, 52);">;</span><span> </span> <span> </span><span class="token" style="color: rgb(0, 0, 255);">static</span><span> </span><span class="token return-type" style="color: rgb(0, 0, 255);">void</span><span> </span><span class="token" style="color: rgb(57, 58, 52);">Main</span><span class="token" style="color: rgb(57, 58, 52);">(</span><span class="token" style="color: rgb(57, 58, 52);">)</span><span> </span><span> </span><span class="token" style="color: rgb(57, 58, 52);">{</span><span> </span><span> Directory</span><span class="token" style="color: rgb(57, 58, 52);">.</span><span class="token" style="color: rgb(57, 58, 52);">CreateDirectory</span><span class="token" style="color: rgb(57, 58, 52);">(</span><span>Path</span><span class="token" style="color: rgb(57, 58, 52);">.</span><span class="token" style="color: rgb(57, 58, 52);">GetDirectoryName</span><span class="token" style="color: rgb(57, 58, 52);">(</span><span>DbPath</span><span class="token" style="color: rgb(57, 58, 52);">)</span><span class="token" style="color: rgb(57, 58, 52);">)</span><span class="token" style="color: rgb(57, 58, 52);">;</span><span> </span><span> </span><span class="token" style="color: rgb(57, 58, 52);">EnsureDatabase</span><span class="token" style="color: rgb(57, 58, 52);">(</span><span class="token" style="color: rgb(57, 58, 52);">)</span><span class="token" style="color: rgb(57, 58, 52);">;</span><span> </span> <span> </span><span class="token" style="color: rgb(0, 0, 255);">var</span><span> hosts </span><span class="token" style="color: rgb(57, 58, 52);">=</span><span> </span><span class="token" style="color: rgb(0, 0, 255);">new</span><span class="token" style="color: rgb(57, 58, 52);">[</span><span class="token" style="color: rgb(57, 58, 52);">]</span><span> </span><span class="token" style="color: rgb(57, 58, 52);">{</span><span> </span><span class="token" style="color: rgb(163, 21, 21);">"8.8.8.8"</span><span class="token" style="color: rgb(57, 58, 52);">,</span><span> </span><span class="token" style="color: rgb(163, 21, 21);">"1.1.1.1"</span><span class="token" style="color: rgb(57, 58, 52);">,</span><span> </span><span class="token" style="color: rgb(163, 21, 21);">"example.com"</span><span> </span><span class="token" style="color: rgb(57, 58, 52);">}</span><span class="token" style="color: rgb(57, 58, 52);">;</span><span> </span><span> </span><span class="token" style="color: rgb(0, 0, 255);">foreach</span><span> </span><span class="token" style="color: rgb(57, 58, 52);">(</span><span class="token" style="color: rgb(0, 0, 255);">var</span><span> host </span><span class="token" style="color: rgb(0, 0, 255);">in</span><span> hosts</span><span class="token" style="color: rgb(57, 58, 52);">)</span><span> </span><span> </span><span class="token" style="color: rgb(57, 58, 52);">{</span><span> </span><span> </span><span class="token" style="color: rgb(0, 0, 255);">var</span><span> result </span><span class="token" style="color: rgb(57, 58, 52);">=</span><span> </span><span class="token" style="color: rgb(57, 58, 52);">PingHost</span><span class="token" style="color: rgb(57, 58, 52);">(</span><span>host</span><span class="token" style="color: rgb(57, 58, 52);">)</span><span class="token" style="color: rgb(57, 58, 52);">;</span><span> </span><span> </span><span class="token" style="color: rgb(57, 58, 52);">SaveResult</span><span class="token" style="color: rgb(57, 58, 52);">(</span><span>result</span><span class="token" style="color: rgb(57, 58, 52);">)</span><span class="token" style="color: rgb(57, 58, 52);">;</span><span> </span><span> Console</span><span class="token" style="color: rgb(57, 58, 52);">.</span><span class="token" style="color: rgb(57, 58, 52);">WriteLine</span><span class="token" style="color: rgb(57, 58, 52);">(</span><span class="token interpolation-string" style="color: rgb(163, 21, 21);">\){result.Timestamp:u} {host} {(result.Success ? \("OK </span><span class="token interpolation-string interpolation expression language-csharp">{</span><span class="token interpolation-string interpolation expression language-csharp">result</span><span class="token interpolation-string interpolation expression language-csharp">.</span><span class="token interpolation-string interpolation expression language-csharp">RoundTrip</span><span class="token interpolation-string interpolation expression language-csharp">}</span><span class="token interpolation-string interpolation expression language-csharp"> ms"</span><span class="token interpolation-string interpolation expression language-csharp"> </span><span class="token interpolation-string interpolation expression language-csharp">:</span><span class="token interpolation-string interpolation expression language-csharp"> </span><span class="token interpolation-string interpolation expression language-csharp">\)“FAIL: {result.Error})}); } } static void EnsureDatabase() { if (!File.Exists(DbPath)) { var engine = new SqlCeEngine(ConnStr); engine.CreateDatabase(); using (var conn = new SqlCeConnection(ConnStr)) { conn.Open(); using (var cmd = conn.CreateCommand()) { cmd.CommandText = @” CREATE TABLE PingResults ( Id INT IDENTITY(1,1) PRIMARY KEY, Host NVARCHAR(255) NOT NULL, Timestamp DATETIME NOT NULL, Success BIT NOT NULL, RoundTripMs INT NULL, ErrorMessage NVARCHAR(1000) NULL )”; cmd.ExecuteNonQuery(); } } } } class PingResult { public string Host; public DateTime Timestamp; public bool Success; public int? RoundTrip; public string Error; } static PingResult PingHost(string host) { var pr = new PingResult { Host = host, Timestamp = DateTime.UtcNow }; try { using (var p = new Ping()) { var reply = p.Send(host, 2000); if (reply.Status == IPStatus.Success) { pr.Success = true; pr.RoundTrip = (int)reply.RoundtripTime; } else { pr.Success = false; pr.Error = reply.Status.ToString(); } } } catch (Exception ex) { pr.Success = false; pr.Error = ex.Message; } return pr; } static void SaveResult(PingResult r) { using (var conn = new SqlCeConnection(ConnStr)) { conn.Open(); using (var cmd = conn.CreateCommand()) { cmd.CommandText = @” INSERT INTO PingResults (Host, Timestamp, Success, RoundTripMs, ErrorMessage) VALUES (@host, @ts, @succ, @rtt, @err)”; cmd.Parameters.AddWithValue(”@host”, r.Host); cmd.Parameters.AddWithValue(”@ts”, r.Timestamp); cmd.Parameters.AddWithValue(”@succ”, r.Success); cmd.Parameters.AddWithValue(”@rtt”, (object)r.RoundTrip ?? DBNull.Value); cmd.Parameters.AddWithValue(”@err”, (object)r.Error ?? DBNull.Value); cmd.ExecuteNonQuery(); } } } }

Scheduling

  • Use Windows Task Scheduler to run the compiled exe at intervals.
  • Optionally add logging or rotate the .sdf file after it reaches a size threshold.

Tips and caveats

  • SQL CE is file-based and not suited for very high write rates or concurrent writers.
  • Use UTC timestamps for consistency.
  • Use small timeouts and consider parallelization with care (avoid many simultaneous writes).
  • For cross-platform or heavier workloads, consider SQLite or a server-based SQL engine.

That’s it — a minimal, working pinger that logs to SQL Server Compact. Adjust hosts, intervals, and error handling for your needs.

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *