Background Windows Service that automatically connects to ZKTeco biometric devices, pulls attendance records, and stores them in SQL Server. Runs continuously with intelligent peak-hour management and bulk processing capabilities.
- ๐ Auto-connects to ZKTeco devices via TCP/IP every 5 minutes
- ๐ฅ Bulk insert operations (10,000 records/batch)
- โธ๏ธ Smart scheduling - pauses during peak hours (check-in/check-out)
- ๐ Retry logic with 3 automatic attempts
- ๐ฏ Incremental sync - only new records (last 365 days)
- ๐ Duplicate prevention using UniqueHash algorithm
graph LR
A[โฐ Timer<br/>Every 5 min] --> B{Peak Hour?}
B -->|Yes| C[โธ๏ธ Skip Cycle]
B -->|No| D[๐ Connect Devices]
D --> E[๐ฅ Pull Records]
E --> F[๐ Check Duplicates]
F --> G[๐พ Bulk Insert]
G --> H[โ
Update Status]
H --> I[โฐ Next Cycle]
C --> I
style A fill:#e3f2fd
style B fill:#fff8e1
style C fill:#ffebee
style D fill:#e8f5e9
style E fill:#f3e5f5
style F fill:#fce4ec
style G fill:#e0f2f1
style H fill:#e8f5e9
style I fill:#e3f2fd
Sync Process Flow:
โฐ Timer โ Check Peak Hour โ Connect Devices (5 parallel)
โ
๐ฅ Pull Records โ Calculate UniqueHash โ Filter New Records
โ
๐พ Bulk Insert (10k/batch) โ Update Status โ Log Results
Note: Works with ZKAttendanceWeb for complete attendance management.
Core: .NET 8.0 Worker Service โข C# 12 โข Entity Framework Core
Device: zkemkeeper.dll (ZKTeco SDK) โข TCP/IP Protocol
Database: SQL Server 2019+ โข EFCore.BulkExtensions
Architecture: Dependency Injection โข Service Layer โข Repository Pattern
ZKAttendanceService/
โโโ ๐ Configuration/ # โ๏ธ Configuration Classes
โ โโโ BranchConfiguration.cs # Branch settings
โ โโโ DeviceConfiguration.cs # Device settings
โ โโโ SyncConfiguration.cs # Sync timing & behavior
โ โโโ WebApiSettings.cs # API integration settings
โ
โโโ ๐ Data/ # ๐พ Database Context
โ โโโ ZKAttendanceWebDbContext.cs # EF Core DbContext
โ โโโ Migrations/ # Database migrations
โ
โโโ ๐ Models/ # ๐ Domain Entities
โ โโโ AttendanceLog.cs # Attendance records
โ โโโ Branch.cs # Branch/location info
โ โโโ Department.cs # Department data
โ โโโ Device.cs # Biometric device info
โ โโโ DeviceError.cs # Device error logs
โ โโโ DeviceStatus.cs # Device health status
โ โโโ Employee.cs # Employee information
โ โโโ Holiday.cs # Holiday calendar
โ โโโ SyncLog.cs # Sync operation logs
โ โโโ SystemSetting.cs # System settings
โ โโโ WorkShift.cs # Work shift definitions
โ
โโโ ๐ Services/ # ๐ง Business Logic Layer
โ โโโ ConfigurationService.cs # Config management
โ โโโ IConfigurationService.cs # Config interface
โ โโโ ISyncService.cs # Sync interface
โ โโโ IWebApiService.cs # API interface
โ โโโ IZKDeviceService.cs # Device interface
โ โโโ PeakHourService.cs # Peak hour logic
โ โโโ SyncService.cs # Main sync operations
โ โโโ WebApiService.cs # Central server sync
โ โโโ ZKDeviceService.cs # ZKTeco device communication
โ
โโโ ๐ ZKTecoSDK/ # ๐ฆ ZKTeco SDK Files
โ โโโ zkemkeeper.dll # ZKTeco COM component
โ
โโโ ๐ appsettings.json # โ๏ธ Configuration File
โโโ ๐ Program.cs # ๐ Application Entry Point
โโโ ๐ Worker.cs # โฐ Background Service Worker
- .NET SDK 8.0+
- SQL Server 2019+
- ZKTeco SDK (zkemkeeper.dll)
- Windows 10/Server 2019+
- ZKTeco Devices
- Clone repository
git clone https://github.com/Faisal-Sahli/ZKAttendanceService.git
cd ZKAttendanceService- Register ZKTeco SDK
regsvr32 "C:\Path\To\zkemkeeper.dll"- Configure settings in
appsettings.json
{
"ConnectionStrings": {
"DefaultConnection": "Server=YOUR_SERVER;Database=ZKAttendance;Trusted_Connection=True;TrustServerCertificate=True;"
},
"DeviceConfiguration": {
"Devices": [
{
"DeviceName": "Main Entrance",
"DeviceIP": "192.168.1.201",
"DevicePort": 4370,
"IsActive": true
}
]
},
"SyncConfiguration": {
"EnableAutoSync": true,
"SyncIntervalMinutes": 5,
"SyncLastNDays": 365,
"MaxRetryAttempts": 3,
"PeakHours": [
{
"Name": "Morning Check-in",
"StartTime": "07:00",
"EndTime": "09:00",
"RunImmediatelyAfter": true
}
]
}
}- Apply migrations
dotnet restore
dotnet ef database update- Run as console (development)
dotnet run- Install as Windows Service (production)
sc create "ZKAttendanceService" binPath="C:\Path\To\ZKAttendanceService.exe"
sc start "ZKAttendanceService"| Setting | Default | Description |
|---|---|---|
EnableAutoSync |
true | Enable/disable auto-sync |
SyncIntervalMinutes |
5 | Frequency in minutes |
SyncLastNDays |
365 | Pull records from last N days |
MaxRetryAttempts |
3 | Retry count on failure |
Configure times when device usage is high to avoid overload:
{
"Name": "Morning Check-in",
"StartTime": "07:00",
"EndTime": "09:00",
"RunImmediatelyAfter": true
}1. Timer triggers every 5 minutes
2. Check if current time is in peak hours
โโ YES โ Skip cycle
โโ NO โ Continue
3. Connect to devices (5 parallel connections)
4. Pull all records using ZKTeco SDK
5. Calculate UniqueHash: {UserId}{DeviceId}{DateTime}
6. Query existing hashes from database
7. Filter only new records
8. Bulk insert (10,000 records/batch)
9. Update device status and create sync log
10. Wait for next cycle
Attempt 1: Immediate
โ Fail โ Wait 2 seconds
Attempt 2: After 2 seconds
โ Fail โ Wait 4 seconds
Attempt 3: After 4 seconds
โ Fail โ Log error and skip
| Metric | Value |
|---|---|
| Sync Speed | 1,000-5,000 records/second |
| Bulk Insert | 10,000 records/batch |
| Parallel Devices | 5 simultaneous |
| Memory Usage | ~100-200 MB |
| CPU Usage | 5-15% during sync |
Optimization Tips:
- Add database indexes on
UniqueHashandAttendanceTime - Adjust batch size in
SyncService.cs - Configure connection pooling
- Balance sync interval with system load
Service fails to start
- Register zkemkeeper.dll:
regsvr32 zkemkeeper.dll - Verify .NET 8.0 Runtime is installed
- Check Windows Event Viewer
Cannot connect to device
- Verify IP and port (default: 4370)
- Test connectivity:
ping 192.168.x.x - Check firewall allows port 4370
Duplicate records
- Verify UniqueHash calculation
- Add index:
CREATE INDEX IX_UniqueHash ON AttendanceLogs(UniqueHash) - Review SyncLogs table
Slow performance
- Increase batch size in SyncService
- Add database indexes
- Reduce
SyncLastNDaysif not needed
| Table | Description |
|---|---|
| AttendanceLogs | Employee attendance records |
| SyncLogs | Sync operation history |
| DeviceStatuses | Device health snapshots |
| Devices | Device configurations |
CREATE TABLE AttendanceLogs (
AttendanceId INT PRIMARY KEY IDENTITY,
BiometricUserId NVARCHAR(50) NOT NULL,
AttendanceTime DATETIME2 NOT NULL,
DeviceId INT NOT NULL,
UniqueHash NVARCHAR(100) NOT NULL UNIQUE,
CreatedDate DATETIME2 DEFAULT GETDATE()
);
CREATE INDEX IX_UniqueHash ON AttendanceLogs(UniqueHash);
CREATE INDEX IX_AttendanceTime ON AttendanceLogs(AttendanceTime DESC);- Auto-sync with retry logic
- Bulk operations & peak hour management
- Incremental sync & duplicate prevention
- Real-time push notifications from devices
- Multi-branch support
- Monitoring dashboard
- Email alerts on failures
- Cloud deployment (Azure)
- Mobile app integration
- AI anomaly detection
- Predictive analytics
Contributions welcome! Please:
- Fork the repository
- Create feature branch (
feature/AmazingFeature) - Write tests and documentation
- Submit pull request
Standards: C# conventions, XML documentation, unit tests, meaningful commits
MIT License - Copyright (c) 2025 Faisal-Sahli
Faisal Al-Sahli - Computer Programmer @ Al-Amal Advanced Medical Company
๐ธ๐ฆ Riyadh, Saudi Arabia โข 2+ years ASP.NET Core โข Biometric Systems Specialist
- ZKAttendanceWeb - Web interface for viewing data
- HRLink System - Complete HR management
โญ Star this repo if you find it useful!
Report Bug โข Request Feature
Made with โค๏ธ by Faisal-Sahli