Windows 服務應用程序

Windows 服務應用程序介紹

Microsoft Windows 服務(即,以前的 NT 服務)使您能夠創建在它們自己的 Windows 會話中可長時間運行的可執行應用程序。這些服務可以在計算機啓動時自動啓動,可以暫停和重新啓動而且不顯示任何用戶界面。這些功能使服務非常適合在服務器上使用,每當需要使用不會影響在同一臺計算機上工作的其他用戶的功能時也適用。還可以在不同於登錄用戶的特定用戶帳戶或默認計算機帳戶的安全上下文中運行服務。有關服務和 Windows 會話的詳細信息,請參見 MSDN Library 中的 Windows SDK 文檔。

通過創建作爲服務安裝的應用程序,可以輕鬆地創建服務。例如,假設要監視性能計數器數據並對閾值做出反應。可以編寫一個偵聽性能計數器數據的 Windows 服務應用程序、部署該應用程序並開始收集和分析數據。

將服務創建爲 Microsoft Visual Studio 項目,並在其中定義代碼,以控制哪些命令可以發送到服務以及接收到這些命令時採取的操作。可以發送到服務的命令包括啓動、暫停、繼續和停止該服務;還可以執行自定義命令。

創建並生成了應用程序後,可以通過運行命令行實用工具 InstallUtil.exe 並將路徑傳遞給服務的可執行文件,來安裝該應用程序。然後可以使用“服務控制管理器”啓動、停止、暫停、繼續和配置服務。這些任務中的許多種也可以在“服務器資源管理器”“服務”節點中或通過使用ServiceController 類來完成。

服務應用程序與其他許多項目類型的功能在幾個方面有所不同:

  • 必須將服務應用程序項目創建的已編譯可執行文件安裝在服務器上,此項目才能以有意義的方式運行。不能通過按 F5 或 F11 來調試或運行服務應用程序;不能立即運行服務或進入其代碼。相反,必須安裝和啓動服務,然後將一個調試器附加到服務的進程中。有關詳細信息,請參閱如何:調試 Windows 服務應用程序

  • 與一些類型的項目不同,對於服務應用程序,必須爲其創建安裝組件。安裝組件在服務器上安裝和註冊服務,並用 Windows“服務控制管理器”爲服務創建一個項。有關詳細信息,請參閱 如何:將安裝程序添加到服務應用程序

  • 服務應用程序的 Main 方法必須爲項目包含的服務發出 Run 命令。 Run 方法將服務加載到適當服務器上的“服務控制管理器”中。如果使用“Windows 服務”項目模板,系統將自動爲您寫入此方法。注意,加載服務與啓動服務不同。有關更多信息,請參見下面的“服務生存期”。

  • Windows 服務應用程序在不同於登錄用戶的交互區域的窗口區域中運行。窗口區域是包含剪貼板、一組全局原子和一組桌面對象的安全對象。由於 Windows 服務的區域不是交互區域,因此 Windows 服務應用程序中引發的對話框將是不可見的,並且可能導致程序停止響應。同樣,錯誤信息應記錄在 Windows 事件日誌中,而不是在用戶界面中引發。

    .NET Framework 支持的 Windows 服務類不支持與交互區域(即登錄用戶)進行交互。同時,.NET Framework 不包含表示區域和桌面的類。如果 Windows 服務必須與其他區域進行交互,則需要訪問非託管的 Windows API。有關詳細信息,請參見 Windows SDK 文檔。

    設計 Windows 服務與用戶或其他區域的交互時必須非常小心,應考慮某些情況,例如沒有登錄的用戶或用戶具有一組意外的桌面對象的情況。在某些情況下,編寫一個在用戶控制下運行的 Windows 應用程序可能更爲妥當。

  • Windows 服務應用程序在各自的安全上下文中運行,並且在用戶登錄到安裝有該程序的 Windows 計算機之前啓動。應仔細計劃在哪些用戶帳戶內運行服務;在系統帳戶下運行的服務比在用戶帳戶下運行的服務具有更多的權限和特權。

服務在其生存期內要經歷幾個內部狀態。首先,將服務安裝在將要運行它的系統上。此過程執行服務項目的安裝程序,並將服務加載到該計算機的“服務控制管理器”中。 “服務控制管理器”是由 Windows 提供的管理服務的核心實用工具。

服務加載後,必須啓動。啓動服務使服務開始運行。可以從“服務控制管理器”、從“服務器資源管理器”或通過調用 Start 方法從代碼啓動服務。Start 方法將處理傳遞給應用程序的 OnStart 方法並處理您在該處定義的任何代碼。

運行的服務可以以這種狀態無限期地存在下去,直到它被停止或暫停或者計算機關閉。服務可以以三種基本狀態之一存在:RunningPaused 或Stopped服務還可以報告掛起命令的狀態:ContinuePendingPausePendingStartPending 或 StopPending這些狀態指示命令已經發出(如暫停正在運行的服務的命令),但尚未執行。您可以查詢 Status 以確定服務的狀態,也可以使用 WaitForStatus 在以上任一狀態出現時執行操作。

可以從“服務控制管理器”、從“服務器資源管理器”或通過從代碼調用方法來暫停、停止或繼續服務。每種操作都可以調用服務中的一個相關過程(OnStopOnPause 或 OnContinue),在其中可以定義當服務狀態更改時所執行的其他處理。

在 Visual Studio 中使用 .NET Framework 可以創建兩種類型的服務。進程中的唯一服務被指定爲 Win32OwnProcess 類型。與其他服務共享進程的服務被指定爲 Win32ShareProcess 類型。可通過查詢 ServiceType 屬性檢索服務類型。

如果查詢不是在 Visual Studio 中創建的現有服務,則偶爾還可能看到其他服務類型。有關這些內容的更多信息,請參見 ServiceType

ServiceController 組件用於連接到已安裝的服務並操作其狀態;使用 ServiceController 組件可以啓動和停止服務、暫停和繼續其運行以及將自定義命令發送到服務。但是,在創建服務應用程序時不需使用 ServiceController 組件。實際上,多數情況下,ServiceController 組件存在於與定義服務的 Windows 服務應用程序不同的應用程序中。

有關詳細信息,請參閱 ServiceController

  • 服務必須創建在“Windows 服務”應用程序項目或其他支持 .NET Framework 的項目中,而該項目在從 ServiceBase 類生成和繼承時創建 .exe 文件。

  • 包含 Windows 服務的項目必須有該項目及其服務的安裝組件。這可以從“屬性”窗口輕鬆實現。有關詳細信息,請參閱 如何:將安裝程序添加到服務應用程序

創建 Windows 服務應用程序

首先,創建項目並設置服務正常運行所必需的值。

創建並配置服務

  1. 在 Visual Studio 中,在菜單欄上,選擇“文件”“新建”“項目”

    “新建項目”對話框隨即打開。

  2. 在 Visual Basic 或 Visual C# 項目模板列表中,選擇“Windows 服務”,然後對項目 MyNewService 命名。選擇“確定”

    項目模板自動添加從 System.ServiceProcess.ServiceBase 繼承的名爲 Service1 的組件類。

  3. “編輯”菜單上,選擇“查找和替換”“在文件中查找”(鍵盤:Ctrl+Shift+F)。更改 Service1 到 MyNewService 的所有匹配項。你將在 Service1.cs、Program.cs 和 Service1.Designer.cs(或它們的 .vb 等效項)中找到實例。

  4. 在 Service1.cs [Design] 或 Service1.vb [Design] 的“屬性”窗口中,將 ServiceName 和 Service1 的(名稱)屬性設置爲 MyNewService(如果尚未設置)。

  5. 在解決方案資源管理器中,將 Service1.cs 重命名爲 MyNewService.cs,或將 Service1.vb 重命名爲 MyNewService.vb


ps :遇到一些問題。
1.啓動之後發現出現問題不能啓動 那麼需要看這個eventvwr.msc
2.啓動後無法讀取配置表,因爲winservice把windows\sysmet32 當做根目錄運行
3.啓動後無法停止服務,是因爲沒在OnStop對程序進行退出處理

pps:
這是我寫的啓動腳本 ExeToService.bat
@echo off
set s32=%windir%\system32
set service_name=%1%
if DEFINED service_name (
sc stop %service_name%
sc delete %service_name%
sc create %service_name% binpath= %~sdp0%service_name%.exe
reg add %RegTab% /f /v Application /t REG_SZ /d %~sdp0%service_name%.exe
reg add %RegTab% /f /v AppDirectory /t REG_SZ /d %~sdp0
sc config %service_name% start= auto 
sc failure %service_name% reset= 60 actions= restart/5
sc start %service_name%
) else (
echo Parameter error
)


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章