<aside> 🧰
기술 스택 — C# · .NET 8 (net8.0-windows) / WinForms 트레이 앱 · .NET Worker Service(BackgroundService) / Npgsql(COPY BINARY) · Microsoft.Data.SqlClient(스트리밍) / EPPlus · FileSystemWatcher / SSH.NET(SFTP) · Named Pipe IPC · Windows EventLog / PowerShell 설치 스크립트
</aside>
<aside> 🎯
한 줄 요약 — 고객사 PC에 상주하며 MES 폴링 · 엑셀 파일 감시 · SFTP 백업을 백그라운드로 수행하는 Windows 서비스와, 트레이 아이콘으로 상태 표시 · 수동 업로드 · 엑셀 양식 편집 · 서비스 제어를 담당하는 WinForms 트레이 앱으로 구성된 데이터 중계기. 제조데이터허브의 "입력 단".
</aside>
| 구성 요소 | 역할 |
|---|---|
| Windows 서비스 | PC 부팅 시 자동 시작, 백그라운드 상주. MES 폴링 · 파일 감시 · SFTP 백업. 트레이 앱을 꺼도 계속 동작 |
| WinForms 트레이 앱 | 트레이 아이콘 상태 표시, 모니터링 창(로그 tail + 업로드 이력), 수동 파일 업로드, 엑셀 양식 GUI 편집기, 서비스 시작·중지 |
| 공유 Core 라이브러리 | 설정 모델 · 로그 · DB 적재 · MES 폴링 · 엑셀 파서 · SFTP 백업. Service와 UI가 모두 참조 |
graph TB
subgraph 원천["데이터 원천"]
MES[("MES DB<br>MSSQL · 읽기 전용")]
XLS["엑셀 파일<br>감시 폴더"]
end
subgraph service["Windows 서비스"]
WORKER["Worker<br>BackgroundService"]
POLL["MesPoller<br>5분 주기 · 워터마크 증분"]
WATCH["FileWatcher<br>폴더 감시 + 디바운싱"]
SFTP["SftpBackup<br>1시간 주기 미러링"]
PIPE["Named Pipe 서버"]
end
subgraph core["Core"]
PARSER["ExcelParser"]
WRITER["DbWriter"]
end
PG[("제조데이터허브<br>PostgreSQL")]
subgraph ui["트레이 앱"]
TRAY["TrayApp"]
MAIN["MainForm 모니터링"]
EDITOR["ExcelSpecEditor"]
end
MES -->|SELECT| POLL
XLS -->|.xlsx 감지| WATCH
WORKER --> POLL & WATCH & SFTP & PIPE
POLL --> WRITER
WATCH --> PARSER --> WRITER
WRITER -->|COPY BINARY| PG
SFTP -->|미러링| BACKUP[("백업 서버")]
TRAY --> MAIN & EDITOR
TRAY <-->|PING / STATS| PIPE
System.Threading.Timer 5분 주기. Interlocked.CompareExchange로 폴링이 길어질 때 다음 tick의 중복 진입 차단.>=).SequentialAccess)으로 메모리 폭주 방지.CREATE TEMP TABLE → COPY ... FROM STDIN (FORMAT BINARY) → 본 테이블 머지. per-row INSERT 대비 수십~수백 배.content_hash(MD5)로 변경 없는 행은 적재 스킵.IsSafeIdentifier 화이트리스트 검증.