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
- Create a new Console App (C#).
- Add references:
- System.Data.SqlServerCe (if using installed SQL CE) or include SQL Server Compact runtime DLLs.
- System.Net.NetworkInformation (for Ping).
- 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.
Leave a Reply