@@ -29,44 +29,113 @@ public static async Task RunAsync()
2929 IPAddress specificIP = IPAddress . Parse ( "127.0.0.1" ) ;
3030 Console . WriteLine ( $ "Starting health check on IP: { specificIP } ") ;
3131 HealthCheckService healthCheckOnIP = smtpServer . EnableHealthCheck ( specificIP , 8081 ) ;
32- await healthCheckOnIP . StartAsync ( ) ;
33- Console . WriteLine ( "Health check available at: http://127.0.0.1:8081/health/\n " ) ;
32+
33+ try
34+ {
35+ await healthCheckOnIP . StartAsync ( ) ;
36+ Console . WriteLine ( "Health check available at: http://127.0.0.1:8081/health/\n " ) ;
37+ }
38+ catch ( Exception ex )
39+ {
40+ Console . WriteLine ( $ "❌ Failed to start health check on { specificIP } : { ex . Message } \n ") ;
41+ }
3442
3543 // Example 2: Bind health check to all interfaces
36- Console . WriteLine ( "Starting health check on all interfaces" ) ;
37- HealthCheckService healthCheckOnAll = smtpServer . EnableHealthCheck ( "0.0.0.0" , 8082 ) ;
38- await healthCheckOnAll . StartAsync ( ) ;
39- Console . WriteLine ( "Health check available at: http://0.0.0.0:8082/health/" ) ;
40- Console . WriteLine ( " and: http://localhost:8082/health/" ) ;
41- Console . WriteLine ( " and: http://[your-ip]:8082/health/\n " ) ;
44+ Console . WriteLine ( "Starting health check on all interfaces (0.0.0.0)" ) ;
45+ HealthCheckService ? healthCheckOnAll = null ;
46+
47+ try
48+ {
49+ healthCheckOnAll = smtpServer . EnableHealthCheck ( "0.0.0.0" , 8082 ) ;
50+ await healthCheckOnAll . StartAsync ( ) ;
51+ Console . WriteLine ( "✓ Health check available at:" ) ;
52+ Console . WriteLine ( " - http://localhost:8082/health/" ) ;
53+ Console . WriteLine ( " - http://[your-ip]:8082/health/\n " ) ;
54+ }
55+ catch ( HttpListenerException ex ) when ( ex . ErrorCode == 5 )
56+ {
57+ Console . WriteLine ( "❌ Access Denied: Administrator privileges required!" ) ;
58+ Console . WriteLine ( "To listen on all interfaces, you need to:" ) ;
59+ Console . WriteLine ( "1. Run as Administrator, or" ) ;
60+ Console . WriteLine ( "2. Add URL reservation (run cmd as admin):" ) ;
61+ Console . WriteLine ( " netsh http add urlacl url=http://+:8082/health/ user=Everyone\n " ) ;
62+ }
63+ catch ( HttpListenerException ex ) when ( ex . ErrorCode == 183 )
64+ {
65+ Console . WriteLine ( "❌ Cannot create a file when that file already exists." ) ;
66+ Console . WriteLine ( "Another application may be using port 8082.\n " ) ;
67+ }
68+ catch ( Exception ex )
69+ {
70+ Console . WriteLine ( $ "❌ Failed: { ex . Message } \n ") ;
71+ }
4272
4373 // Example 3: Bind to specific hostname
44- Console . WriteLine ( "Starting health check with hostname" ) ;
45- HealthCheckService healthCheckWithHost = smtpServer . EnableHealthCheck ( "localhost" , 8083 ) ;
46- await healthCheckWithHost . StartAsync ( ) ;
47- Console . WriteLine ( "Health check available at: http://localhost:8083/health/\n " ) ;
74+ Console . WriteLine ( "Starting health check with hostname (localhost)" ) ;
75+ HealthCheckService ? healthCheckWithHost = null ;
76+
77+ try
78+ {
79+ healthCheckWithHost = smtpServer . EnableHealthCheck ( "localhost" , 8083 ) ;
80+ await healthCheckWithHost . StartAsync ( ) ;
81+ Console . WriteLine ( "✓ Health check available at: http://localhost:8083/health/\n " ) ;
82+ }
83+ catch ( Exception ex )
84+ {
85+ Console . WriteLine ( $ "❌ Failed to start health check on localhost: { ex . Message } \n ") ;
86+ }
4887
4988 // Example 4: IPv6 binding (if supported)
89+ HealthCheckService ? healthCheckIPv6 = null ;
90+
5091 try
5192 {
5293 IPAddress ipv6Address = IPAddress . IPv6Loopback ;
5394 Console . WriteLine ( $ "Starting health check on IPv6: { ipv6Address } ") ;
54- HealthCheckService healthCheckIPv6 = smtpServer . EnableHealthCheck ( ipv6Address , 8084 ) ;
95+ healthCheckIPv6 = smtpServer . EnableHealthCheck ( ipv6Address , 8084 ) ;
5596 await healthCheckIPv6 . StartAsync ( ) ;
56- Console . WriteLine ( "Health check available at: http://[::1]:8084/health/\n " ) ;
97+ Console . WriteLine ( "✓ Health check available at: http://[::1]:8084/health/\n " ) ;
98+ }
99+ catch ( HttpListenerException ex )
100+ {
101+ Console . WriteLine ( $ "❌ IPv6 binding failed: { ex . Message } ") ;
102+ Console . WriteLine ( "IPv6 may not be supported or enabled on this system.\n " ) ;
57103 }
58104 catch ( Exception ex )
59105 {
60- Console . WriteLine ( $ "IPv6 not supported: { ex . Message } \n ") ;
106+ Console . WriteLine ( $ "❌ IPv6 not supported: { ex . Message } \n ") ;
61107 }
62108
109+ // Show summary
110+ Console . WriteLine ( "=====================================" ) ;
111+ Console . WriteLine ( "Summary:" ) ;
112+ Console . WriteLine ( "ℹ Localhost bindings usually work without admin rights" ) ;
113+ Console . WriteLine ( "ℹ Binding to 0.0.0.0 or specific IPs requires admin rights" ) ;
114+ Console . WriteLine ( "ℹ Use URL ACL reservations for non-admin access" ) ;
115+ Console . WriteLine ( "=====================================" ) ;
116+
63117 Console . WriteLine ( "\n Press any key to stop..." ) ;
64118 Console . ReadKey ( ) ;
65119
66120 // Stop all health check services
67- await healthCheckOnIP . StopAsync ( ) ;
68- await healthCheckOnAll . StopAsync ( ) ;
69- await healthCheckWithHost . StopAsync ( ) ;
121+ Console . WriteLine ( "\n Stopping services..." ) ;
122+
123+ try { await healthCheckOnIP . StopAsync ( ) ; } catch { }
124+ if ( healthCheckOnAll != null )
125+ {
126+ try { await healthCheckOnAll . StopAsync ( ) ; } catch { }
127+ }
128+
129+ if ( healthCheckWithHost != null )
130+ {
131+ try { await healthCheckWithHost . StopAsync ( ) ; } catch { }
132+ }
133+
134+ if ( healthCheckIPv6 != null )
135+ {
136+ try { await healthCheckIPv6 . StopAsync ( ) ; } catch { }
137+ }
138+
70139 await smtpServer . StopAsync ( ) ;
71140
72141 Console . WriteLine ( "Example completed." ) ;
0 commit comments