本附件中的程序只是一個沒有任何功能的框架程序,程序本身是一個MFC對話框,也是一個NT服務,可以在進入windows之後,用戶登陸之前就開始運行。
服務的名稱、顯示名稱、依賴服務 可以在資源中的String Table中修改,分別對應於IDS_SZSERVICENAME、IDS_SZSERVICEDISPLAYNAME、IDS_SZDEPENDENCIES;需要注意的是String Table中不可以存放空字符串,所以在沒有依賴服務的情況下,我在IDS_SZDEPENDENCIES中放了一個空格;
注冊服務和卸載服務只需要在運行時加上命令行參數 -install 和 -remove;為了便於調試,附加了一個參數 -debug,可以不經由NT服務管理器而啟動。有關於NT服務的代碼皆來自於MSDN。
對於非MFC的對話框程序而言,可以簡化很多代碼;MFC對話框比non-MFC對話框多處理了一個WM_ENDSESSION消息,否則用戶在注銷並重新登陸之後,程序將失去響應。這是本程序的重點所在。
在程序開始處使用了SetCurrentDirectory將當前目錄設置為了模塊所在目錄,否則當前目錄就是NT服務管理器所在目錄,所以調試的時候需要注意,當前目錄不是工程所在目錄了,而是工程目錄下Debug目錄,這非常方便。
本程序還增加了系統托盤功能,對於系統托盤,本程序處理了兩個特殊情況,一個是系統托盤彈出的菜單在失去焦點時會自動消失,另一個是在Explorer.exe崩潰重建時系統托盤也自動重建。
使用-debug參數運行時跟普通程序一樣,省略;運行和停止這個服務可以在NT服務管理器中進行,也可以使用控制台命令net shart/stop,如果你願意增加一些代碼,也可以直接啟動。停止這個服務還可以使用系統托盤中的Exit菜單。
NT服務常用於無人職守運行,因此也應該避免用戶不小心退出程序,所以本人將最小化按鈕和關閉按鈕的功能變成了隱藏,恢復顯示和退出程序可以使用系統托盤中的菜單。
對於不熟悉NT服務的用戶需要注意,因為NT服務會在用戶登陸之前就開始運行,因此比如連接遠程共享就應該如下處理:
1.將網絡通訊的服務名稱加到IDS_SZDEPENDENCIES中,這樣確保網絡通訊服務在次服務之前啟動;
2.因為用戶還沒有登陸,所以沒有默認的用戶名,所以應該提供用戶名和密碼去訪問遠程共享。 當然這些都不是本程序應該說明的事。
很多文章說到要在NT服務程序中顯示界面,必須要OpenWindowStation(_T("winsta0")...),但本人沒有這樣做,這是一個疑問。
最後,為了避免法律糾紛,特此聲明:本代碼是在業余時間編寫,雖曾用於部分商業項目,但所有權不屬於任何公司,而本人也不需要任何所有權。
測試平台:win2k pro,VC++6.0 + SP5
本文配套源碼