將作為一個服務應用程序的一部分存在的服務提供基類。 ServiceBase 必須派生自創建新的服務類時。
程序集: System.ServiceProcess(位於 System.ServiceProcess.dll)
System.MarshalByRefObject
System.ComponentModel.Component
System.ServiceProcess.ServiceBase
| 名稱 | 說明 | |
|---|---|---|
![]() |
ServiceBase() |
創建 ServiceBase 類的新實例。 |
| 名稱 | 說明 | |
|---|---|---|
![]() |
AutoLog |
指示是否報表在事件日志中的啟動、 停止、 暫停和繼續命令。 |
![]() |
CanHandlePowerEvent |
獲取或設置一個值,該值指示服務是否可以處理計算機電源狀態更改的通知。 |
![]() |
CanHandleSessionChangeEvent |
獲取或設置一個值,指示服務是否可以處理會話從終端服務器會話接收到的更改事件。 |
![]() |
CanPauseAndContinue |
獲取或設置一個值,該值指示是否可以暫停和恢復該服務。 |
![]() |
CanRaiseEvents |
獲取一個值,該值指示組件是否可以引發一個事件。(繼承自 Component。) |
![]() |
CanShutdown |
獲取或設置一個值,該值在系統關閉時是否應通知服務。 |
![]() |
CanStop |
獲取或設置一個值,指示它啟動后是否可以停止服務。 |
![]() |
Container |
獲取 IContainer ,其中包含 Component。(繼承自 Component。) |
![]() |
DesignMode | |
![]() |
EventLog |
獲取可用於寫入應用程序事件日志服務命令調用,如啟動和停止通知事件日志。 |
![]() |
Events | |
![]() |
ExitCode |
獲取或設置該服務的退出代碼。 |
![]() |
ServiceHandle |
獲取服務的服務控制句柄。 |
![]() |
ServiceName |
獲取或設置用於標識服務對系統的短名稱。 |
![]() |
Site |
| 名稱 | 說明 | |
|---|---|---|
![]() |
CreateObjRef(Type) |
創建包含所有生成代理用於與遠程對象進行通信所需的相關信息的對象。(繼承自 MarshalByRefObject。) |
![]() |
Dispose() | |
![]() |
Dispose(Boolean) |
處置由 ServiceBase 占用的資源(內存除外)。(覆蓋 Component.Dispose(Boolean)。) |
![]() |
Equals(Object) |
確定指定的對象是否等於當前對象。(繼承自 Object。) |
![]() |
Finalize() | |
![]() |
GetHashCode() |
作為默認哈希函數。(繼承自 Object。) |
![]() |
GetLifetimeService() |
檢索當前生存期服務對象,用於控制此實例的生存期策略。(繼承自 MarshalByRefObject。) |
![]() |
GetService(Type) | |
![]() |
GetType() | |
![]() |
InitializeLifetimeService() |
獲取生存期服務對象來控制此實例的生存期策略。(繼承自 MarshalByRefObject。) |
![]() |
MemberwiseClone() | |
![]() |
MemberwiseClone(Boolean) |
創建當前的淺表副本MarshalByRefObject對象。(繼承自 MarshalByRefObject。) |
![]() |
OnContinue() |
在派生類中實現時 OnContinue 時繼續命令發送到服務的服務控制管理器 (SCM) 運行。 指定當某個服務后繼續正常工作正在暫停時要執行的操作。 |
![]() |
OnCustomCommand(Int32) |
在派生類中實現時 OnCustomCommand 服務控制管理器 (SCM) 向服務傳遞自定義命令時執行。 指定具有指定的參數值的命令發生時要采取的操作。 |
![]() |
OnPause() |
派生類中實現時,暫停命令發送到服務的服務控制管理器 (SCM) 時執行。 指定當服務就會暫停時要執行的操作。 |
![]() |
OnPowerEvent(PowerBroadcastStatus) |
派生類中實現時,在計算機的電源狀態已發生更改時執行。 這適用於便攜式計算機,當他們進入掛起模式,這不是系統關閉相同。 |
![]() |
OnSessionChange(SessionChangeDescription) |
在終端服務器會話中接收的更改事件時執行。 |
![]() |
OnShutdown() |
派生類中實現時,在系統關閉時執行。 指定在系統關閉之前應該發生什么。 |
![]() |
OnStart(String[]) |
派生類中實現時,在由服務控制管理器 (SCM) 或在操作系統啟動時 (對於自動啟動的服務) 時,將啟動命令發送到服務時執行。 指定當服務啟動時要執行的操作。 |
![]() |
OnStop() |
派生類中實現時,停止命令發送到服務的服務控制管理器 (SCM) 時執行。 指定當服務停止運行時要執行的操作。 |
![]() |
RequestAdditionalTime(Int32) |
掛起的操作的請求更多時間。 |
![]() ![]() |
Run(ServiceBase) |
與服務控制管理器 (SCM) 注冊服務的可執行文件。 |
![]() ![]() |
Run(ServiceBase[]) |
注冊多個服務的可執行文件與服務控制管理器 (SCM)。 |
![]() |
ServiceMainCallback(Int32, IntPtr) |
此 API 支持 產品 基礎結構,不應從代碼直接使用。 注冊命令處理程序,然后啟動該服務。 |
![]() |
Stop() |
停止正在執行的服務。 |
![]() |
ToString() |
| 名稱 | 說明 | |
|---|---|---|
![]() ![]() |
MaxNameLength |
指示服務名稱的最大大小。 |
派生自 ServiceBase 在服務應用程序中定義您的服務類時。 任何有用的服務的替代 OnStart 和 OnStop 方法。 對於其他功能,您可以重寫 OnPause 和 OnContinue 用特定行為的服務狀態變化。
服務是長時間運行的可執行文件不支持用戶界面,並可能無法在已登錄的用戶帳戶下運行。 該服務可以沒有任何登錄到計算機的用戶的情況下運行。
默認情況下,服務不是管理員帳戶相同的系統帳戶下運行。 不能更改系統帳戶的權限。 或者,可以使用 ServiceProcessInstaller 來指定將在其下運行服務的用戶帳戶。
一個可執行文件可以包含多個服務,但必須包含一個單獨 ServiceInstaller 為每個服務。 ServiceInstaller 實例向系統注冊該服務。 安裝程序還將每個服務與事件日志用於記錄服務命令相關聯。 main() 函數可執行文件中的定義的服務應該運行。 該服務的當前工作目錄是系統目錄中,不是可執行文件所在的目錄。
當您啟動服務時,系統查找可執行文件,並運行 OnStart 可執行文件中包含該服務的方法。 但是,運行該服務不是運行可執行文件一樣。 可執行文件僅加載服務。 訪問此服務時 (例如,啟動和停止) 通過服務控制管理器。
可執行文件調用 ServiceBase 派生類的第一個構造函數時調用該服務上的啟動。 OnStart 構造函數執行后立即調用命令處理方法。 構造函數不會執行加載服務后,在首次后再次因此有必要單獨的由中執行的構造函數執行的處理 OnStart。 可以通過釋放任何資源 OnStop 應中創建 OnStart。 在構造函數中創建資源會阻止他們正在正確創建,如果服務啟動后再次 OnStop 具有已釋放的資源。
服務控制管理器 (SCM) 使您能夠與服務交互。 SCM 可用於將開始、 停止、 暫停、 繼續或自定義命令傳遞到服務。 SCM 使用的值 CanStop 和 CanPauseAndContinue 來確定服務是否接受停止、 暫停或繼續命令。 停止、 暫停和繼續在 SCM 的上下文菜單才中啟用相應的屬性 CanStop 或 CanPauseAndContinue 是 true 在服務類中。 如果啟用,則將命令傳遞到服務,並 OnStop, ,OnPause, ,或 OnContinue 調用。 如果CanStop, ,CanShutdown, ,或 CanPauseAndContinue 是 false, ,相應的命令處理方法 (如 OnStop) 將不會處理,即使您已實現該方法。
您可以使用 ServiceController 類以編程方式執行 SCM 未使用的用戶界面。 您可以自動化可在控制台中執行的任務。 如果 CanStop, ,CanShutdown, ,或 CanPauseAndContinue 是 true 但尚未實現相應的命令處理方法 (如 OnStop) 系統引發異常,並將忽略該命令。
不需要實現 OnStart, ,OnStop, ,或在任何其他方法 ServiceBase。 但是,該服務的行為詳見 OnStart, ,因此,在最低限度下,應重寫該成員。main() 函數的可執行文件中注冊服務可執行文件使用服務控制管理器中,通過調用 Run 方法。 ServiceName 屬性 ServiceBase 對象傳遞給 Run 方法必須與匹配 ServiceName 該服務的服務安裝程序的屬性。
您可以使用 InstallUtil.exe 若要在您的系統上安裝服務。
自 1.1 起可用
此類型的所有公共靜態(Visual Basic 中的 已共享 在 Visual Basic 中)成員都是線程安全的。不保證所有實例成員都是線程安全的。
ServiceBase 類
命名空間:System.ServiceProcess
程序集:System.ServiceProcess(在 system.serviceprocess.dll 中)
當在服務應用程序中定義服務類時從 ServiceBase 派生。任何有用的服務均將重寫 OnStart 和 OnStop 方法。對於其他功能,可以用特定行為重寫 OnPause 和 OnContinue 來響應服務狀態的更改。
服務是長時間運行的可執行文件,它不支持用戶界面,在登錄的用戶帳戶下可能無法運行。服務可以在沒有任何用戶登錄計算機的情況下運行。
默認情況下,服務在“系統”帳戶下運行,該帳戶與“管理員”帳戶不同。不能更改“系統”帳戶的權限。或者,可以使用 ServiceProcessInstaller 指定運行服務時將使用的用戶帳戶。
一個可執行文件可以包含多項服務,但對每項服務均必須包含一個單獨的 ServiceInstaller。ServiceInstaller 實例在系統中注冊服務。安裝程序還將每項服務與一個事件日志關聯,您可以使用該日志記錄服務命令。可執行文件中的 main() 函數定義哪些服務應該運行。服務的當前工作目錄是系統目錄,而不是可執行文件所位於的目錄。
當啟動某項服務時,系統將定位相應的可執行文件,並運行該服務的 OnStart 方法(它包含在可執行文件內)。但是,運行服務與運行可執行文件並不相同。可執行文件僅加載服務。服務則通過“服務控制管理器”訪問(例如啟動和停止)。
當您對服務首次調用“開始”時,可執行文件調用 ServiceBase 派生類的構造函數。在構造函數執行之后將立即調用 OnStart 命令處理方法。在服務首次加載之后,構造函數不會再次執行,因此有必要將構造函數執行的處理和 OnStart 執行的處理分開。可以由 OnStop 釋放的任何資源都應在 OnStart 中創建。如果服務在 OnStop 釋放資源后再次啟動,那么,在構造函數中創建資源會妨礙這些資源的正確創建。
“服務控制管理器”(SCM) 提供與服務交互的方式。可以使用 SCM 將“開始”(Start)、“停止”(Stop)、“暫停”(Pause)、“繼續”(Continue) 或自定義命令傳遞到服務中。SCM 使用 CanStop 和 CanPauseAndContinue 的值,決定服務是否接受“停止”、“暫停”或“繼續”命令。僅當服務類中相應的屬性 CanStop 或 CanPauseAndContinue 為 true 時,才會在 SCM 的上下文菜單中啟用“停止”、“暫停”或“繼續”。如果已啟用,則相應的命令將傳遞到服務,並且調用 OnStop、OnPause 或 OnContinue。如果 CanStop、CanShutdown 或 CanPauseAndContinue 為 false,則即使已實現相應的命令處理方法(如 OnStop),也不會予以處理。
可以使用 ServiceController 類通過編程實現 SCM 使用用戶界面實現的功能。可以自動處理控制台中可用的任務。如果 CanStop、CanShutdown 或 CanPauseAndContinue 為 true,但尚未實現相應的命令處理方法(如 OnStop),則系統引發異常並忽略該命令。
不必在 ServiceBase 中實現 OnStart、OnStop 或其他任何方法。然而,服務的行為在 OnStart 中加以描述,因此至少應重寫該成員。必須在可執行文件的 main() 函數中設置服務的服務名稱。在 main() 中設置的服務名稱必須與服務安裝程序的 ServiceName 屬性完全匹配。
可以使用 InstallUtil.exe 在系統中安裝服務。
1 // Turn on logging to the event log. 2 #define LOGEVENTS 3 4 using System; 5 using System.IO; 6 using System.Threading; 7 using System.Collections.Generic; 8 using System.ComponentModel; 9 using System.Data; 10 using System.Diagnostics; 11 using System.ServiceProcess; 12 using System.Text; 13 using Microsoft.Win32; 14 using System.Runtime.InteropServices; 15 using System.Windows.Forms; 16 17 namespace ServiceSample 18 { 19 // Define custom commands for the SimpleService. 20 public enum SimpleServiceCustomCommands { StopWorker = 128, RestartWorker, CheckWorker }; 21 [StructLayout(LayoutKind.Sequential)] 22 public struct SERVICE_STATUS 23 { 24 public int serviceType; 25 public int currentState; 26 public int controlsAccepted; 27 public int win32ExitCode; 28 public int serviceSpecificExitCode; 29 public int checkPoint; 30 public int waitHint; 31 } 32 33 public enum State 34 { 35 SERVICE_STOPPED = 0x00000001, 36 SERVICE_START_PENDING = 0x00000002, 37 SERVICE_STOP_PENDING = 0x00000003, 38 SERVICE_RUNNING = 0x00000004, 39 SERVICE_CONTINUE_PENDING = 0x00000005, 40 SERVICE_PAUSE_PENDING = 0x00000006, 41 SERVICE_PAUSED = 0x00000007, 42 } 43 44 // Define a simple service implementation. 45 public class SimpleService : System.ServiceProcess.ServiceBase 46 { 47 private static int userCount = 0; 48 private static ManualResetEvent pause = new ManualResetEvent(false); 49 50 [DllImport("ADVAPI32.DLL", EntryPoint = "SetServiceStatus")] 51 public static extern bool SetServiceStatus( 52 IntPtr hServiceStatus, 53 SERVICE_STATUS lpServiceStatus 54 ); 55 private SERVICE_STATUS myServiceStatus; 56 57 private Thread workerThread = null; 58 59 public SimpleService() 60 { 61 CanPauseAndContinue = true; 62 CanHandleSessionChangeEvent = true; 63 ServiceName = "SimpleService"; 64 } 65 66 static void Main() 67 { 68 #if LOGEVENTS 69 EventLog.WriteEntry("SimpleService.Main", DateTime.Now.ToLongTimeString() + 70 " - Service main method starting..."); 71 #endif 72 73 // Load the service into memory. 74 System.ServiceProcess.ServiceBase.Run(new SimpleService()); 75 76 #if LOGEVENTS 77 EventLog.WriteEntry("SimpleService.Main", DateTime.Now.ToLongTimeString() + 78 " - Service main method exiting..."); 79 #endif 80 81 } 82 83 private void InitializeComponent() 84 { 85 // Initialize the operating properties for the service. 86 this.CanPauseAndContinue = true; 87 this.CanShutdown = true; 88 this.CanHandleSessionChangeEvent = true; 89 this.ServiceName = "SimpleService"; 90 } 91 92 // Start the service. 93 protected override void OnStart(string[] args) 94 { 95 IntPtr handle = this.ServiceHandle; 96 myServiceStatus.currentState = (int)State.SERVICE_START_PENDING; 97 SetServiceStatus(handle, myServiceStatus); 98 99 // Start a separate thread that does the actual work. 100 101 if ((workerThread == null) || 102 ((workerThread.ThreadState & 103 (System.Threading.ThreadState.Unstarted | System.Threading.ThreadState.Stopped)) != 0)) 104 { 105 #if LOGEVENTS 106 EventLog.WriteEntry("SimpleService.OnStart", DateTime.Now.ToLongTimeString() + 107 " - Starting the service worker thread."); 108 #endif 109 110 workerThread = new Thread(new ThreadStart(ServiceWorkerMethod)); 111 workerThread.Start(); 112 } 113 if (workerThread != null) 114 { 115 #if LOGEVENTS 116 EventLog.WriteEntry("SimpleService.OnStart", DateTime.Now.ToLongTimeString() + 117 " - Worker thread state = " + 118 workerThread.ThreadState.ToString()); 119 #endif 120 } 121 myServiceStatus.currentState = (int)State.SERVICE_RUNNING; 122 SetServiceStatus(handle, myServiceStatus); 123 124 } 125 126 // Stop this service. 127 protected override void OnStop() 128 { 129 // New in .NET Framework version 2.0. 130 this.RequestAdditionalTime(4000); 131 // Signal the worker thread to exit. 132 if ((workerThread != null) && (workerThread.IsAlive)) 133 { 134 #if LOGEVENTS 135 EventLog.WriteEntry("SimpleService.OnStop", DateTime.Now.ToLongTimeString() + 136 " - Stopping the service worker thread."); 137 #endif 138 pause.Reset(); 139 Thread.Sleep(5000); 140 workerThread.Abort(); 141 142 } 143 if (workerThread != null) 144 { 145 #if LOGEVENTS 146 EventLog.WriteEntry("SimpleService.OnStop", DateTime.Now.ToLongTimeString() + 147 " - OnStop Worker thread state = " + 148 workerThread.ThreadState.ToString()); 149 #endif 150 } 151 // Indicate a successful exit. 152 this.ExitCode = 0; 153 } 154 155 // Pause the service. 156 protected override void OnPause() 157 { 158 // Pause the worker thread. 159 if ((workerThread != null) && 160 (workerThread.IsAlive) && 161 ((workerThread.ThreadState & 162 (System.Threading.ThreadState.Suspended | System.Threading.ThreadState.SuspendRequested)) == 0)) 163 { 164 #if LOGEVENTS 165 EventLog.WriteEntry("SimpleService.OnPause", DateTime.Now.ToLongTimeString() + 166 " - Pausing the service worker thread."); 167 #endif 168 169 pause.Reset(); 170 Thread.Sleep(5000); 171 } 172 173 if (workerThread != null) 174 { 175 #if LOGEVENTS 176 EventLog.WriteEntry("SimpleService.OnPause", DateTime.Now.ToLongTimeString() + 177 " OnPause - Worker thread state = " + 178 workerThread.ThreadState.ToString()); 179 #endif 180 } 181 } 182 183 // Continue a paused service. 184 protected override void OnContinue() 185 { 186 187 // Signal the worker thread to continue. 188 if ((workerThread != null) && 189 ((workerThread.ThreadState & 190 (System.Threading.ThreadState.Suspended | System.Threading.ThreadState.SuspendRequested)) != 0)) 191 { 192 #if LOGEVENTS 193 EventLog.WriteEntry("SimpleService.OnContinue", DateTime.Now.ToLongTimeString() + 194 " - Resuming the service worker thread."); 195 196 #endif 197 pause.Set(); 198 } 199 if (workerThread != null) 200 { 201 #if LOGEVENTS 202 EventLog.WriteEntry("SimpleService.OnContinue", DateTime.Now.ToLongTimeString() + 203 " OnContinue - Worker thread state = " + 204 workerThread.ThreadState.ToString()); 205 #endif 206 } 207 } 208 209 // Handle a custom command. 210 protected override void OnCustomCommand(int command) 211 { 212 #if LOGEVENTS 213 EventLog.WriteEntry("SimpleService.OnCustomCommand", DateTime.Now.ToLongTimeString() + 214 " - Custom command received: " + 215 command.ToString()); 216 #endif 217 218 // If the custom command is recognized, 219 // signal the worker thread appropriately. 220 221 switch (command) 222 { 223 case (int)SimpleServiceCustomCommands.StopWorker: 224 // Signal the worker thread to terminate. 225 // For this custom command, the main service 226 // continues to run without a worker thread. 227 OnStop(); 228 break; 229 230 case (int)SimpleServiceCustomCommands.RestartWorker: 231 232 // Restart the worker thread if necessary. 233 OnStart(null); 234 break; 235 236 case (int)SimpleServiceCustomCommands.CheckWorker: 237 #if LOGEVENTS 238 // Log the current worker thread state. 239 EventLog.WriteEntry("SimpleService.OnCustomCommand", DateTime.Now.ToLongTimeString() + 240 " OnCustomCommand - Worker thread state = " + 241 workerThread.ThreadState.ToString()); 242 #endif 243 244 break; 245 246 default: 247 #if LOGEVENTS 248 EventLog.WriteEntry("SimpleService.OnCustomCommand", 249 DateTime.Now.ToLongTimeString()); 250 #endif 251 break; 252 } 253 } 254 // Handle a session change notice 255 protected override void OnSessionChange(SessionChangeDescription changeDescription) 256 { 257 #if LOGEVENTS 258 EventLog.WriteEntry("SimpleService.OnSessionChange", DateTime.Now.ToLongTimeString() + 259 " - Session change notice received: " + 260 changeDescription.Reason.ToString() + " Session ID: " + 261 changeDescription.SessionId.ToString()); 262 #endif 263 264 switch (changeDescription.Reason) 265 { 266 case SessionChangeReason.SessionLogon: 267 userCount += 1; 268 #if LOGEVENTS 269 EventLog.WriteEntry("SimpleService.OnSessionChange", 270 DateTime.Now.ToLongTimeString() + 271 " SessionLogon, total users: " + 272 userCount.ToString()); 273 #endif 274 break; 275 276 case SessionChangeReason.SessionLogoff: 277 278 userCount -= 1; 279 #if LOGEVENTS 280 EventLog.WriteEntry("SimpleService.OnSessionChange", 281 DateTime.Now.ToLongTimeString() + 282 " SessionLogoff, total users: " + 283 userCount.ToString()); 284 #endif 285 break; 286 case SessionChangeReason.RemoteConnect: 287 userCount += 1; 288 #if LOGEVENTS 289 EventLog.WriteEntry("SimpleService.OnSessionChange", 290 DateTime.Now.ToLongTimeString() + 291 " RemoteConnect, total users: " + 292 userCount.ToString()); 293 #endif 294 break; 295 296 case SessionChangeReason.RemoteDisconnect: 297 298 userCount -= 1; 299 #if LOGEVENTS 300 EventLog.WriteEntry("SimpleService.OnSessionChange", 301 DateTime.Now.ToLongTimeString() + 302 " RemoteDisconnect, total users: " + 303 userCount.ToString()); 304 #endif 305 break; 306 case SessionChangeReason.SessionLock: 307 #if LOGEVENTS 308 EventLog.WriteEntry("SimpleService.OnSessionChange", 309 DateTime.Now.ToLongTimeString() + 310 " SessionLock"); 311 #endif 312 break; 313 314 case SessionChangeReason.SessionUnlock: 315 #if LOGEVENTS 316 EventLog.WriteEntry("SimpleService.OnSessionChange", 317 DateTime.Now.ToLongTimeString() + 318 " SessionUnlock"); 319 #endif 320 break; 321 322 default: 323 324 break; 325 } 326 } 327 // Define a simple method that runs as the worker thread for 328 // the service. 329 public void ServiceWorkerMethod() 330 { 331 #if LOGEVENTS 332 EventLog.WriteEntry("SimpleService.WorkerThread", DateTime.Now.ToLongTimeString() + 333 " - Starting the service worker thread."); 334 #endif 335 336 try 337 { 338 do 339 { 340 // Simulate 4 seconds of work. 341 Thread.Sleep(4000); 342 // Block if the service is paused or is shutting down. 343 pause.WaitOne(); 344 #if LOGEVENTS 345 EventLog.WriteEntry("SimpleService.WorkerThread", DateTime.Now.ToLongTimeString() + 346 " - heartbeat cycle."); 347 #endif 348 } 349 while (true); 350 } 351 catch (ThreadAbortException) 352 { 353 // Another thread has signalled that this worker 354 // thread must terminate. Typically, this occurs when 355 // the main service thread receives a service stop 356 // command. 357 358 // Write a trace line indicating that the worker thread 359 // is exiting. Notice that this simple thread does 360 // not have any local objects or data to clean up. 361 #if LOGEVENTS 362 EventLog.WriteEntry("SimpleService.WorkerThread", DateTime.Now.ToLongTimeString() + 363 " - Thread abort signaled."); 364 #endif 365 } 366 #if LOGEVENTS 367 368 EventLog.WriteEntry("SimpleService.WorkerThread", DateTime.Now.ToLongTimeString() + 369 " - Exiting the service worker thread."); 370 #endif 371 372 } 373 } 374 }









注意