什么是服務(wù)
維基百科: Architecture of Windows NT 、Windows service
The term "service" in this context generally refers to a callable routine, or set of callable routines. This is distinct from the concept of a "service process", which is a user mode component somewhat analogous to a daemon in Unix-like operating systems.
從 Microsoft 技術(shù)文檔 找的一些描述:
A service is an application type that runs in the system background and is similar to a UNIX daemon application. Services provide core operating system features, such as Web serving, event logging, file serving, help and support, printing, cryptography, and error reporting. With the Services snap-in, you can manage services on local or remote computers.
A service is a long-running executable that does not support a user interface, and which might not run under the logged-on user account. The service can run without any user being logged on to the computer.
Microsoft Windows services, formerly known as NT services, enable you to create long-running executable applications that run in their own Windows sessions. These services can be automatically started when the computer boots, can be paused and restarted, and do not show any user interface. These features make services ideal for use on a server or whenever you need long-running functionality that does not interfere with other users who are working on the same computer. You can also run services in the security context of a specific user account that is different from the logged-on user or the default computer account.
You can easily create services by creating an application that is installed as a service. For example, suppose you want to monitor performance counter data and react to threshold values. You could write a Windows Service application that listens to the performance counter data, deploy the application, and begin collecting and analyzing data.
A service application conforms to the interface rules of the Service Control Manager (SCM). It can be started automatically at system boot, by a user through the Services control panel applet, or by an application that uses the service functions. Services can execute even when no user is logged on to the system.
A driver service conforms to the device driver protocols. It is similar to a service application, but it does not interact with the SCM. For simplicity, the term service refers to a service application in this overview.
按我的理解,服務(wù)就是一個(gè)抽象概念哪怔,是一套被設(shè)計(jì)用于管理那些 需要長(zhǎng)時(shí)間運(yùn)行屠阻、具有依賴關(guān)系戏阅、沒(méi)有用戶界面夜郁、不需要用戶登錄燃辖、需要特殊權(quán)限锯玛、可跟隨系統(tǒng)啟動(dòng)而自動(dòng)運(yùn)行的程序 的體系結(jié)構(gòu),而相關(guān)的數(shù)據(jù)庫(kù)踢涌、程序通孽、進(jìn)程都是其中不可或缺的一部分。用戶向系統(tǒng)注冊(cè)服務(wù)后便由系統(tǒng)來(lái)自動(dòng)調(diào)度服務(wù)而無(wú)需用戶參與睁壁。任務(wù)管理器的服務(wù)標(biāo)簽頁(yè)中背苦,每行數(shù)據(jù)可以表示一個(gè)服務(wù),實(shí)際數(shù)據(jù)存儲(chǔ)于注冊(cè)表中:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services
服務(wù)這個(gè)術(shù)語(yǔ)更傾向于描述程序的運(yùn)行方式潘明,比如以服務(wù)的方式運(yùn)行( run as a service )行剂。
Windows 中的服務(wù)和 Linux 中的服務(wù)從目的性上( 后臺(tái)運(yùn)行、開(kāi)機(jī)啟動(dòng)等 )來(lái)說(shuō)比較類似钳降,只不過(guò)實(shí)現(xiàn)方式和運(yùn)行機(jī)制有所不同厚宰。 Linux 服務(wù)通常會(huì)在 /etc/init.d
目錄下有一個(gè)對(duì)應(yīng)的配置腳本( 參考 ),比起在 Windows 上更直觀易懂,配置服務(wù)也更容易铲觉。
服務(wù)變更歷史
- What's New in Services for Windows 8
- What's New in Services for Windows 7
- Service Changes for Windows Vista
服務(wù)與程序和進(jìn)程的關(guān)系
類似的問(wèn)答
- What's the difference between an Application, a Process, and a Service?
- What is the difference between 'Application' and 'Process' in OS X?
- windows 下的服務(wù)和進(jìn)程有什么區(qū)別澈蝙?
相關(guān)術(shù)語(yǔ)解釋
操作系統(tǒng)
Operating System
操作系統(tǒng)是管理計(jì)算機(jī)資源并為用戶提供服務(wù)的系統(tǒng)軟件,作為硬件與應(yīng)用軟件之間的接口撵幽,操作系統(tǒng)起著承上啟下的作用灯荧。
計(jì)算機(jī)系統(tǒng)大體上可以分為三個(gè)部分:硬件、系統(tǒng)軟件和應(yīng)用軟件盐杂。硬件是所有軟件運(yùn)行的物質(zhì)基礎(chǔ)逗载。而操作系統(tǒng)(簡(jiǎn)稱 OS)則是最重要的系統(tǒng)軟件。是管理計(jì)算機(jī)系統(tǒng)資源链烈、控制程序執(zhí)行的系統(tǒng)軟件厉斟。操作系統(tǒng)作為計(jì)算機(jī)用戶與計(jì)算機(jī)硬件之間的接口程序,向用戶和應(yīng)用軟件提供各種服務(wù)强衡,合理組織計(jì)算機(jī)工作流程擦秽,并為用戶使用計(jì)算機(jī)提供良好運(yùn)行環(huán)境。
操作系統(tǒng)的核心任務(wù)是管理計(jì)算機(jī)系統(tǒng)中的資源食侮。操作系統(tǒng)為用戶提供簡(jiǎn)單、有效的資源使用方法目胡,分配資源使用權(quán)锯七,解決資源爭(zhēng)用沖突,跟蹤資源使用狀況誉己,最大限度地實(shí)現(xiàn)資源共享眉尸,提高資源利用率。而操作系統(tǒng)地其他任務(wù)巨双,如擴(kuò)充機(jī)器功能噪猾、屏蔽使用細(xì)節(jié)、方便用戶使用筑累、合理組織工作流程袱蜡、管理人機(jī)界面等,都是圍繞著資源管理任務(wù)實(shí)現(xiàn)的慢宗。
資源
所謂資源坪蚁,泛指在計(jì)算機(jī)系統(tǒng)中,用戶能夠使用的各種硬件和軟件部分镜沽。計(jì)算機(jī)系統(tǒng)中可以使用的硬件資源主要是處理機(jī)敏晤、存儲(chǔ)器、輸入/輸出設(shè)備等缅茉。而軟件資源則包括相應(yīng)的程序和數(shù)據(jù)等嘴脾。
程序
Computer Program
在早期的計(jì)算機(jī)中,人們是直接用機(jī)器語(yǔ)言(即機(jī)器指令代碼)來(lái)編寫(xiě)程序的蔬墩,這種方式編寫(xiě)的程序稱為 手編程序 译打。這種用機(jī)器語(yǔ)言書(shū)寫(xiě)的程序耗拓,計(jì)算機(jī)完全可以“識(shí)別”并能執(zhí)行,所以又叫做 目的程序 扶平。
用某種高級(jí)語(yǔ)言或匯編語(yǔ)言編寫(xiě)的程序稱為源程序 帆离,源程序不能直接在計(jì)算機(jī)上執(zhí)行。如果源程序是用匯編語(yǔ)言編寫(xiě)的结澄,則需要一個(gè)匯編程序?qū)⑵浞g成目標(biāo)程序后才能執(zhí)行哥谷。如果源程序是用某種高級(jí)語(yǔ)言編寫(xiě)的,則需要對(duì)應(yīng)的解釋程序或者編譯程序?qū)ζ溥M(jìn)行翻譯麻献,然后在機(jī)器上運(yùn)行们妥。
通常用源代碼( Source code ,人類可讀的符合程序設(shè)計(jì)語(yǔ)言規(guī)范書(shū)寫(xiě)的文本文件 )表示源程序勉吻,而程序泛指目的程序监婶,即可執(zhí)行的文件( Executable ),不需要關(guān)聯(lián) 打開(kāi)方式 就能雙擊打開(kāi)的文件齿桃。在 Windows 中除了常見(jiàn)的 exe 文件和批處理文件外惑惶,還可以用注冊(cè)表查詢 HKEY_CLASSES_ROOT 中數(shù)據(jù)為 "%1" %*
的項(xiàng)。
- What are the differences between a Program, an Executable, and a Process?
- 操作系統(tǒng)是如何運(yùn)行可執(zhí)行文件的短纵?
- 什么是程序(Program)
軟件
Software
軟件是一系列文檔带污、程序以及其正常運(yùn)行所需的相關(guān)數(shù)據(jù)的集合。我們常說(shuō)的軟件( 手機(jī)上的 APP )一般指的是運(yùn)行在操作系統(tǒng)之上的應(yīng)用軟件( Application )香到,比如 QQ 鱼冀,打開(kāi)安裝目錄可以看到除了 exe 文件外還有一堆其他的文件。
應(yīng)用軟件是指計(jì)算機(jī)用戶利用計(jì)算機(jī)的軟件悠就、硬件資源為某一專門的應(yīng)用目的而開(kāi)發(fā)的軟件千绪。例如,科學(xué)計(jì)算梗脾、工程設(shè)計(jì)荸型、數(shù)據(jù)處理、事務(wù)處理和過(guò)程控制等方面的程序炸茧,以及文字處理軟件帆疟、表格處理軟件、輔助設(shè)計(jì)軟件(CAD)和實(shí)時(shí)處理軟件等宇立。
應(yīng)用與任務(wù)
App & Task
對(duì)應(yīng) win10 任務(wù)管理器中進(jìn)程標(biāo)簽頁(yè)下的應(yīng)用分類踪宠,每個(gè)應(yīng)用展開(kāi)后會(huì)有任務(wù)。應(yīng)用是存在前臺(tái)窗口與用戶進(jìn)行交互的主進(jìn)程妈嘹,任務(wù)是其子進(jìn)程或者抽象出來(lái)的窗口柳琢。像常用的 合并任務(wù)欄按鈕 設(shè)置項(xiàng),沒(méi)合并前顯示全部的窗口任務(wù),合并后只顯示應(yīng)用柬脸。( 打開(kāi)任務(wù)欄設(shè)置 )
它們和進(jìn)程之間的對(duì)應(yīng)關(guān)系不太好描述他去,自行感受吧:
- 打開(kāi)兩個(gè)文件夾窗口后,可以看到 1 個(gè)資源管理器應(yīng)用倒堕、 2 個(gè)文件夾任務(wù)灾测、 1 個(gè) explorer.exe 進(jìn)程。
- 使用
regedit -m
命令打開(kāi)兩個(gè)注冊(cè)表編輯器垦巴,可以看到 2 個(gè)應(yīng)用媳搪、 每個(gè)應(yīng)用 1 個(gè)任務(wù)、 2 個(gè) regedit.exe 進(jìn)程骤宣。 - 打開(kāi) nginx 后不顯示應(yīng)用和任務(wù)秦爆,但可以看到 2 個(gè) nginx.exe 后臺(tái)進(jìn)程。
- 像 VMware 虛擬機(jī)憔披,最小化在托盤時(shí)不顯示應(yīng)用和任務(wù)等限,而雙擊打開(kāi)后可以看到 1 個(gè)應(yīng)用、 2 個(gè)任務(wù)芬膝、 3 個(gè)進(jìn)程望门。
進(jìn)程
Process
進(jìn)程是程序的一次執(zhí)行,該程序可以和其他程序并發(fā)執(zhí)行锰霜。進(jìn)程通常是由程序筹误、數(shù)據(jù)和進(jìn)程控制塊(PCB)組成的。
在操作系統(tǒng)中锈遥,通常使用 進(jìn)程(process) 這一概念描述程序的動(dòng)態(tài)執(zhí)行過(guò)程纫事。通俗地講勘畔,程序是靜態(tài)實(shí)體所灸,而進(jìn)程是動(dòng)態(tài)實(shí)體,是執(zhí)行中的程序炫七。進(jìn)程不僅僅包含程序代碼爬立,也包含了當(dāng)前的狀態(tài)(這由程序計(jì)數(shù)器和處理機(jī)中的相關(guān)寄存器表示)和資源。因此万哪,如果兩個(gè)用戶用同樣一段代碼分別執(zhí)行相同功能的程序侠驯,那么其中的每一個(gè)都是一個(gè)獨(dú)立的進(jìn)程。雖然其代碼是相同的奕巍,但是數(shù)據(jù)卻未必相同吟策。
進(jìn)程是可并發(fā)執(zhí)行的程序在一個(gè)數(shù)據(jù)集合上的運(yùn)行過(guò)程,是系統(tǒng)進(jìn)行資源分配和調(diào)度的基本單位的止,是線程的容器檩坚。迄今為止對(duì)這一概念還沒(méi)有一個(gè)確切的統(tǒng)一的描述。一個(gè)進(jìn)程是特定程序的一個(gè)實(shí)例( instance ),在運(yùn)行過(guò)程中可以創(chuàng)建自己的子進(jìn)程匾委。 后臺(tái)進(jìn)程 就是不與用戶進(jìn)行交互( 隱藏起來(lái) )的進(jìn)程拖叙。
程序和進(jìn)程就是 名詞 與 現(xiàn)在進(jìn)行時(shí) 的關(guān)系,常見(jiàn)的比喻是菜譜和做菜過(guò)程赂乐。
- 進(jìn)程基礎(chǔ)知識(shí)
- 進(jìn)程到底是什么薯鳍?
- 并發(fā)編程 — 進(jìn)程
- 什么是進(jìn)程
- 進(jìn)程和程序的區(qū)別有哪幾個(gè)方面?
- 進(jìn)程和線程是不是操作系統(tǒng)才有的概念挨措?
服務(wù)程序
一種符合 服務(wù)控制管理器 (SCM) 接口規(guī)范的應(yīng)用程序挖滤,即 Service Program ,是服務(wù)啟動(dòng)實(shí)際所執(zhí)行的可執(zhí)行文件运嗜。( 詳見(jiàn)下文 )
以上引用內(nèi)容摘自 計(jì)算機(jī)組成原理第 4 版 和 軟件設(shè)計(jì)師教程(第三版)(修訂版) 壶辜,多年以后再回顧教材發(fā)現(xiàn)上課學(xué)的東西早忘得一干二凈了,還好書(shū)留著可以當(dāng)詞典用担租。
它們之間的關(guān)系:
- 用戶雙擊 > 運(yùn)行 程序 > 產(chǎn)生 進(jìn)程 砸民。
- 啟動(dòng)服務(wù) > 運(yùn)行 服務(wù)程序 > 產(chǎn)生 服務(wù)進(jìn)程 。
這些術(shù)語(yǔ)本就比較抽象奋救,再加上翻譯岭参、口語(yǔ)化、場(chǎng)景( 開(kāi)發(fā)還是使用 )等等因素就容易造成歧義令人困惑尝艘。就像 1+1=2
一樣演侯,不需要糾結(jié)為什么是這樣,只需要知道這是約定成俗的背亥,了解多了自然就懂了秒际。這些術(shù)語(yǔ)的存在是為了幫助人們更容易理解復(fù)雜抽象的計(jì)算機(jī)軟件體系結(jié)構(gòu)〗坪海口語(yǔ)中的服務(wù)通常在各個(gè)語(yǔ)境中分別指代服務(wù)本身娄徊、服務(wù)程序和服務(wù)進(jìn)程,能明白其中的含義就行了盾戴。
什么是服務(wù)控制管理器 (SCM)
Service Control Manager (SCM) is a special system process under the Windows NT family of operating systems, which starts, stops and interacts with Windows service processes. It is located in the
%SystemRoot%\System32\services.exe
executable. Service processes interact with SCM through a well-defined API, and the same API is used internally by the interactive Windows service management tools such as the MMC snap-inServices.msc
and the command-line Service Control utilitysc.exe
. Terminating this file is used as a method of causing the Blue Screen of Death.
我們都知道服務(wù)設(shè)置為自動(dòng)后就能開(kāi)機(jī)啟動(dòng)寄锐,而這個(gè)操控者就是 SCM 。SCM 是一個(gè)特殊的系統(tǒng)進(jìn)程尖啡,它執(zhí)行各種與服務(wù)有關(guān)的任務(wù)橄仆。它跟隨系統(tǒng)啟動(dòng)而運(yùn)行,之后它便會(huì)啟動(dòng)所有設(shè)置了 自動(dòng)啟動(dòng) 的服務(wù)以及它們所依賴的 手動(dòng)啟動(dòng) 的服務(wù)衅斩。SCM 維護(hù)了一個(gè)數(shù)據(jù)庫(kù)來(lái)存儲(chǔ)已安裝的服務(wù)盆顾,并提供了安全統(tǒng)一的方式來(lái)管理它們。
SCM 就是整個(gè)服務(wù)體系的核心畏梆,由它直接管理服務(wù)的一切配置和行為您宪,它提供一系列 函數(shù) 供其他程序調(diào)用以間接控制服務(wù):
- 維護(hù)已安裝服務(wù)的數(shù)據(jù)庫(kù)惫搏。
- 在系統(tǒng)啟動(dòng)時(shí)或按需啟動(dòng)服務(wù)和驅(qū)動(dòng)程序服務(wù)。
- 枚舉已安裝的服務(wù)和驅(qū)動(dòng)程序服務(wù)蚕涤。
- 維護(hù)運(yùn)行服務(wù)和驅(qū)動(dòng)服務(wù)的狀態(tài)信息筐赔。
- 將控制請(qǐng)求傳輸?shù)秸谶\(yùn)行的服務(wù)。
- 鎖定和解鎖服務(wù)數(shù)據(jù)庫(kù)揖铜。
調(diào)用這些函數(shù)的程序根據(jù)職能主要分為以下幾類:
服務(wù)程序
Service Program
為一個(gè)或多個(gè)服務(wù)提供可執(zhí)行代碼的應(yīng)用程序茴丰。主要用到了連接 SCM 和修改服務(wù)狀態(tài)的函數(shù)。一些 服務(wù)程序 還會(huì)通過(guò)命令行參數(shù)實(shí)現(xiàn)自 安裝 的功能天吓,比如 mysqld --install
贿肩。
通常 服務(wù)程序 作為控制臺(tái)程序直接運(yùn)行而不是通過(guò)服務(wù)運(yùn)行時(shí)會(huì)報(bào)錯(cuò):
# 參考 StartServiceCtrlDispatcher 的返回值
1063 (ERROR_FAILED_SERVICE_CONTROLLER_CONNECT)
服務(wù)配置程序
Service Configuration Program
主要用于增刪改查 SCM 數(shù)據(jù)庫(kù)中服務(wù)配置信息的程序。雖然可以通過(guò)注冊(cè)表管理數(shù)據(jù)庫(kù)龄寞,但還是應(yīng)該只使用 SCM 提供的相關(guān)函數(shù)以確保配置的正確性汰规。系統(tǒng)自帶的命令行工具 Sc.exe 就包含此類功能。
服務(wù)控制程序
Service Control Program
主要用于 啟動(dòng)服務(wù)程序 和 控制服務(wù)進(jìn)程 的程序物邑,后面簡(jiǎn)稱 SCP 溜哮。它們只是向 SCM 發(fā)送請(qǐng)求,再由 SCM 轉(zhuǎn)發(fā)給服務(wù)色解。系統(tǒng)自帶的命令行工具 Sc.exe 茂嗓、net.exe 就包含此類功能。
SCM 以串行的方式依次處理請(qǐng)求科阎,一個(gè)服務(wù)處理完一個(gè)請(qǐng)求后 SCM 才會(huì)發(fā)送下一個(gè)請(qǐng)求述吸。因此如果服務(wù)正忙于處理請(qǐng)求時(shí) ,之后的 StartService 和 ControlService 都會(huì)阻塞锣笨,超時(shí)( 30 秒 )直接返回錯(cuò)誤蝌矛。
SCM 同時(shí)是一個(gè) RPC 服務(wù)器,因此服務(wù)配置和服務(wù)控制程序可以管理遠(yuǎn)程主機(jī)上的服務(wù)错英。
進(jìn)一步了解服務(wù)
服務(wù)屬性
所有屬性值詳見(jiàn)下面的鏈接:
- Win32_Service class
- CreateService Parameters
- sc.exe create
- Database of Installed Services
- Service Record List
- ServiceInstaller Properties
提一下 ServiceName 入撒、 DisplayName 、 Description 這三個(gè)屬性走趋, ServiceName 才是每個(gè)服務(wù)的唯一標(biāo)識(shí)衅金,比較時(shí)不區(qū)分大小寫(xiě)噪伊,另外兩個(gè)則是顯示名稱和描述簿煌,是為了幫助用戶識(shí)別這個(gè)服務(wù)的作用。另外鉴吹, DisplayName 還用于 NET START 命令姨伟。然而在 任務(wù)管理器 和 服務(wù) 以及其他第三方工具的界面中通常只顯示兩個(gè)字段( 名稱和描述 ),內(nèi)容則是這三個(gè)屬性混用或者組合而成的豆励,很混亂夺荒。
服務(wù)類型
名稱 | 數(shù)值 | 說(shuō)明 |
---|---|---|
SERVICE_ADAPTER | 0x00000004 | 保留的瞒渠。 |
SERVICE_FILE_SYSTEM_DRIVER | 0x00000002 | 文件系統(tǒng)驅(qū)動(dòng)程序服務(wù)。 |
SERVICE_KERNEL_DRIVER | 0x00000001 | 設(shè)備驅(qū)動(dòng)程序服務(wù)技扼。 |
SERVICE_RECOGNIZER_DRIVER | 0x00000008 | 保留的伍玖。 |
SERVICE_WIN32_OWN_PROCESS | 0x00000010 | 獨(dú)占一個(gè)進(jìn)程的服務(wù)蟋座。 |
SERVICE_WIN32_SHARE_PROCESS | 0x00000020 | 與其他服務(wù)共享一個(gè)進(jìn)程的服務(wù)秽誊。 |
SERVICE_USER_OWN_PROCESS | 0x00000050 | 在登錄的用戶帳戶下運(yùn)行的獨(dú)占服務(wù)矮固。 |
SERVICE_USER_SHARE_PROCESS | 0x00000060 | 在登錄的用戶帳戶下運(yùn)行的共享服務(wù)顽腾。 |
SERVICE_INTERACTIVE_PROCESS | 0x00000100 | 可交互的服務(wù) 蓄髓。Windows Vista 起服務(wù)不能直接與用戶交互锡足。 |
服務(wù)可以通過(guò)調(diào)用 SetServiceBits 函數(shù)來(lái)注冊(cè)其他類型信息别洪。調(diào)用 NetServerGetInfo 和 NetServerEnum 函數(shù)獲取支持的服務(wù)類型飘弧。( 來(lái)源 )
SERVICE_INTERACTIVE_PROCESS 需要和 SERVICE_WIN32_OWN_PROCESS 或 SERVICE_WIN32_SHARE_PROCESS 組合使用榄笙,并且要在 LocalSystem 帳戶上下文中運(yùn)行邪狞。
- 驅(qū)動(dòng)程序服務(wù) 的運(yùn)行和管理方式有所不同,本文先不做深入了解了茅撞。
-
用戶服務(wù) 在用戶登錄時(shí)使用模板創(chuàng)建帆卓,退出時(shí)刪除,起到用戶級(jí)別的隔離米丘。名稱形如
OneSyncSvc_ff97b
鳞疲,這個(gè)后綴是每次登錄后隨機(jī)生成的。 - 保護(hù)反惡意軟件服務(wù)
服務(wù)啟動(dòng)類型
名稱 | 數(shù)值 | 說(shuō)明 |
---|---|---|
SERVICE_AUTO_START | 0x00000002 | 系統(tǒng)啟動(dòng)時(shí)由 SCM 自動(dòng)啟動(dòng)的服務(wù)蠕蚜。詳見(jiàn) 自動(dòng)啟動(dòng)服務(wù) 尚洽。DelayedAutostart 設(shè)為 1 時(shí)表示 自動(dòng)(延遲啟動(dòng)) 。 |
SERVICE_BOOT_START | 0x00000000 | 由系統(tǒng)加載程序啟動(dòng)的設(shè)備驅(qū)動(dòng)程序靶累。此值僅對(duì)驅(qū)動(dòng)程序服務(wù)有效腺毫。 |
SERVICE_DEMAND_START | 0x00000003 | 手動(dòng),當(dāng)進(jìn)程調(diào)用 StartService 函數(shù)時(shí)由 SCM 啟動(dòng)的服務(wù) 挣柬。詳見(jiàn) 按需啟動(dòng)服務(wù) 潮酒。 |
SERVICE_DISABLED | 0x00000004 | 禁止啟動(dòng)的服務(wù)。嘗試啟動(dòng)此類服務(wù)會(huì)返回 錯(cuò)誤代碼 ERROR_SERVICE_DISABLED 邪蛔。 |
SERVICE_SYSTEM_START | 0x00000001 | 由 IoInitSystem 函數(shù)啟動(dòng)的設(shè)備驅(qū)動(dòng)程序急黎。此值僅對(duì)驅(qū)動(dòng)程序服務(wù)有效。 |
服務(wù)狀態(tài)
名稱 | 數(shù)值 | 說(shuō)明 |
---|---|---|
SERVICE_CONTINUE_PENDING | 0x00000005 | 服務(wù)正在恢復(fù)侧到。 |
SERVICE_PAUSE_PENDING | 0x00000006 | 服務(wù)正在暫停勃教。 |
SERVICE_PAUSED | 0x00000007 | 服務(wù)已暫停。 |
SERVICE_RUNNING | 0x00000004 | 服務(wù)正在運(yùn)行匠抗。 |
SERVICE_START_PENDING | 0x00000002 | 服務(wù)正在啟動(dòng)故源。 |
SERVICE_STOP_PENDING | 0x00000003 | 服務(wù)正在停止。 |
SERVICE_STOPPED | 0x00000001 | 服務(wù)未運(yùn)行汞贸。 |
服務(wù)運(yùn)行后需要及時(shí)正確地向 SCM 更新自己最新的 狀態(tài) 绳军,這樣 SCP 才能通過(guò) SCM 查詢服務(wù)的狀態(tài)印机。服務(wù)的狀態(tài)決定了服務(wù)和 SCM 之間該如何交互。例如门驾,如果服務(wù)正處于 SERVICE_STOP_PENDING 狀態(tài)射赛,則 SCM 不會(huì)向服務(wù)發(fā)送進(jìn)一步的控制請(qǐng)求,因?yàn)榇藸顟B(tài)指示服務(wù)正在關(guān)閉奶是。
The following table shows the action of the SCM in each of the possible service states.
服務(wù)的初始化狀態(tài)是 SERVICE_STOPPED 咒劲,主要的合法轉(zhuǎn)換過(guò)程見(jiàn)下圖:
服務(wù)程序啟動(dòng)過(guò)程
看不到 StartService 的底層實(shí)現(xiàn),我猜測(cè) SCM 啟動(dòng)服務(wù) 的大概流程應(yīng)該是這樣的( 參考 ):
SCP 調(diào)用 StartService 诫隅。
-
SCM 準(zhǔn)備啟動(dòng)服務(wù)腐魂。
如果多個(gè)服務(wù)共享一個(gè)進(jìn)程且該進(jìn)程已存在則獲取進(jìn)程對(duì)應(yīng)的連接甸箱。
-
否則創(chuàng)建新的服務(wù)進(jìn)程( 將登錄令牌分配給進(jìn)程 )育叁,等待建立連接。
在 入口點(diǎn) 中調(diào)用 StartServiceCtrlDispatcher :
- 建立主線程和 SCM 之間的連接( 命名管道 )芍殖。
- 將主線程作為 dispatcher 線程 駐留在一個(gè)循環(huán)內(nèi)接收來(lái)自 SCM 的請(qǐng)求豪嗽。
- 直到發(fā)生錯(cuò)誤或者進(jìn)程中所有服務(wù)都結(jié)束了才會(huì)使主線程繼續(xù)往下執(zhí)行。
默認(rèn)超過(guò) 30 秒沒(méi)有調(diào)用 StartServiceCtrlDispatcher 會(huì)直接終止進(jìn)程豌骏。
事件查看器 > 自定義視圖 > 管理事件 > 服務(wù)啟動(dòng)失敗修改超時(shí)時(shí)間 ( 重啟才會(huì)生效 ):
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control ServicesPipeTimeout = 60000
-
連接建立時(shí)龟梦, SCM 發(fā)送 啟動(dòng)請(qǐng)求 并傳遞啟動(dòng)參數(shù)。
當(dāng)收到通知用于執(zhí)行 ServiceMain 的線程創(chuàng)建成功后窃躲, StartService 就直接返回以繼續(xù)執(zhí)行 SCP 中的代碼( 可定期 查詢 或者 監(jiān)聽(tīng) 服務(wù)的最新?tīng)顟B(tài) )计贰。
-
SCM 繼續(xù)等待進(jìn)程退出( 表示啟動(dòng)失敗 )或者報(bào)告 SERVICE_RUNNING 狀態(tài)。
如果服務(wù)在 80 秒內(nèi)沒(méi)有更新其狀態(tài)蒂窒,則 SCM 會(huì)認(rèn)為服務(wù)發(fā)生了錯(cuò)誤躁倒,將記錄一個(gè)事件并停止服務(wù)( 不確定是否會(huì)終止進(jìn)程 )。
當(dāng) SCM 得知服務(wù)正在運(yùn)行后便會(huì) 釋放 服務(wù)鎖 洒琢。
dispatcher 線程 的請(qǐng)求處理流程:
-
啟動(dòng)請(qǐng)求
新建線程調(diào)起此服務(wù)對(duì)應(yīng)的 ServiceMain 并通知 SCM 線程創(chuàng)建成功秧秉。
-
調(diào)用 RegisterServiceCtrlHandler 注冊(cè) Service Control Handler 函數(shù)以監(jiān)聽(tīng)來(lái)自 SCM 的 控制請(qǐng)求 。
由于調(diào)用 SetServiceStatus 依賴于 RegisterServiceCtrlHandler 返回的 服務(wù)狀態(tài)句柄 纬凤,所以只有將 RegisterServiceCtrlHandler 放置在 ServiceMain 中最開(kāi)始的位置才能夠在發(fā)生錯(cuò)誤時(shí)總能將狀態(tài)更新為 SERVICE_STOPPED 福贞。
-
執(zhí)行服務(wù)初始化邏輯并更新服務(wù)狀態(tài)為 SERVICE_RUNNING 撩嚼。
初始化過(guò)程應(yīng)盡可能快( 不超過(guò) 1 秒 )停士,否則要考慮特殊方法去優(yōu)化挖帘。
-
執(zhí)行服務(wù)實(shí)際的業(yè)務(wù)邏輯。
避免直接調(diào)用 ExitThread 來(lái)結(jié)束線程恋技,這樣做會(huì)跳過(guò)清理任務(wù)而導(dǎo)致內(nèi)存泄漏拇舀。
-
-
控制請(qǐng)求 ( ControlService )
在當(dāng)前線程上下文中調(diào)起 Handler ,根據(jù)請(qǐng)求的 控制代碼 執(zhí)行對(duì)應(yīng)的業(yè)務(wù)代碼蜻底。
Handler 被調(diào)用的時(shí)候骄崩,如果業(yè)務(wù)代碼會(huì)導(dǎo)致服務(wù)狀態(tài)發(fā)生變化則一定要記得調(diào)用 SetServiceStatus ,如果不會(huì)導(dǎo)致?tīng)顟B(tài)變化則不需要調(diào)用薄辅。
控制代碼 除了已規(guī)定的幾種外還可以是用戶自定義的代碼( 128-255 )如果有 權(quán)限 的話要拂。
以上流程只是我根據(jù)文檔整理出來(lái)的,跟著代碼走一遍也許能有進(jìn)一步的理解站楚⊥讯瑁看文檔的時(shí)候注意結(jié)合 About Services 、Using Services 窿春、winsvc 拉一,因?yàn)橐粋€(gè)概念的內(nèi)容可能會(huì)分散在三個(gè)部分中。
什么是 Svchost
前面提到了 與其他服務(wù)共享一個(gè)進(jìn)程的服務(wù) 旧乞,可以在多個(gè)服務(wù)之間共享代碼蔚润,一個(gè)常見(jiàn)的例子就是服務(wù)主機(jī) Svchost.exe ,它用來(lái)托管系統(tǒng)內(nèi)部的服務(wù)( DLL 形式 )尺栖。
Svchost.exe ( 服務(wù)主機(jī) 嫡纠,或 SvcHost )是一個(gè)系統(tǒng)進(jìn)程,它可以承載 Windows NT 系列操作系統(tǒng)中的一個(gè)或多個(gè) Windows 服務(wù) 延赌。Svchost 在共享服務(wù)進(jìn)程的實(shí)現(xiàn)中是必不可少的货徙,其中多個(gè)服務(wù)可以共享一個(gè)進(jìn)程以減少資源消耗。將多個(gè)服務(wù)組合到一個(gè)進(jìn)程中可以節(jié)省計(jì)算資源皮胡,這一考慮是 NT 設(shè)計(jì)人員特別關(guān)心的痴颊,因?yàn)閯?chuàng)建 Windows 進(jìn)程比其他操作系統(tǒng)( 例如 Unix 系列 )需要更多時(shí)間和消耗更多內(nèi)存。但是屡贺,如果其中一項(xiàng)服務(wù)導(dǎo)致未處理的異常蠢棱,則整個(gè)進(jìn)程可能會(huì)崩潰。此外甩栈,最終用戶可能更難以識(shí)別組件服務(wù)泻仙。
svchost 進(jìn)程是在 Windows 2000 中引入的,盡管從 Windows NT 3.1 開(kāi)始就存在對(duì)共享服務(wù)進(jìn)程的底層支持量没。
它正確的位置應(yīng)該位于系統(tǒng)盤根目錄的 \Windows\system32 目錄下( 64 位系統(tǒng)則亦在系統(tǒng)盤根目錄的 \Windows\SysWOW64 )玉转。 如果在其他地方看到,那么很可能是病毒程序殴蹄。
微軟的 文檔 中明確指出了 Svchost.exe 保留供操作系統(tǒng)使用究抓,不應(yīng)由非 Windows 服務(wù)使用猾担,開(kāi)發(fā)者應(yīng)實(shí)現(xiàn)自己的服務(wù)托管程序 ,所以使用 Svchost.exe 偽裝自己的行為就是在 耍流氓 刺下。
早期的 Windows 一般只有有數(shù)幾個(gè) svchost 進(jìn)程绑嘹,之后才慢慢增多并劃分成不同的主機(jī)組,不同組的服務(wù)在不同實(shí)例中運(yùn)行橘茉。服務(wù)組是根據(jù)安全需求劃分的工腋。
Windows 10 1703 起有了新的改動(dòng):內(nèi)存大于 3.5 GB 的機(jī)器自動(dòng)為每個(gè)共享服務(wù)( 有例外 )分配一個(gè)單獨(dú)進(jìn)程。所以在任務(wù)管理器中看到密密麻麻一堆 svchost 進(jìn)程是很正常的現(xiàn)象畅卓。單獨(dú)進(jìn)程會(huì)造成內(nèi)存開(kāi)銷增大( 大概 500 MB )擅腰,但好處是加強(qiáng)了安全性、穩(wěn)定性翁潘、可擴(kuò)展性惕鼓,降低了故障排除的開(kāi)銷,以及更細(xì)致的資源管理和診斷數(shù)據(jù)唐础。( 參考 )
Svchost 參考資料
-
創(chuàng)建 SvcHost.exe 調(diào)用的服務(wù)原理與實(shí)踐
Svchost 本身只是作為服務(wù)宿主箱歧,并不實(shí)現(xiàn)任何服務(wù)功能,需要 Svchost 啟動(dòng)的服務(wù)以動(dòng)態(tài)鏈接庫(kù)形式實(shí)現(xiàn)一膨,在安裝這些服務(wù)時(shí)呀邢,把服務(wù)的可執(zhí)行程序指向 Svchost ,啟動(dòng)這些服務(wù)時(shí)由 Svchost 調(diào)用相應(yīng)服務(wù)的動(dòng)態(tài)鏈接庫(kù)來(lái)啟動(dòng)服務(wù)豹绪。
那么 Svchost 如何知道某一服務(wù)是由哪個(gè)動(dòng)態(tài)鏈接庫(kù)負(fù)責(zé)呢价淌?這不是由服務(wù)的可執(zhí)行程序路徑中的參數(shù)部分提供的,而是服務(wù)在注冊(cè)表中的參數(shù)設(shè)置的瞒津,注冊(cè)表中服務(wù)下邊有一個(gè) Parameters 子鍵其中的 ServiceDll 表明該服務(wù)由哪個(gè)動(dòng)態(tài)鏈接庫(kù)負(fù)責(zé)蝉衣。并且所有這些服務(wù)動(dòng)態(tài)鏈接庫(kù)都必須要導(dǎo)出一個(gè) ServiceMain() 函數(shù),用來(lái)處理服務(wù)任務(wù)巷蚪。
svchost.exe 啟動(dòng)服務(wù)原理(如何查看系統(tǒng)服務(wù)究竟啟動(dòng)了哪個(gè)文件)
How to determine what services are running under a SVCHOST.EXE process
安全之路 —— 利用 SVCHost.exe 系統(tǒng)服務(wù)實(shí)現(xiàn)后門自啟動(dòng)
編寫(xiě)在 Svchost 中運(yùn)行的 DLL
- How to run a dll as a service?
- SVCHOST 啟動(dòng)服務(wù)實(shí)戰(zhàn)
- Window 服務(wù)學(xué)習(xí)筆記
- SvcHostDemo
- DllSrv
注冊(cè)任何程序?yàn)榉?wù)
一個(gè)標(biāo)準(zhǔn)的 服務(wù)程序 必須包含以下幾點(diǎn) SCM 接口規(guī)范:
并不是說(shuō) SCM 會(huì)檢測(cè)程序里是否暴露了這幾個(gè)函數(shù), 而是一個(gè)服務(wù)想要正常運(yùn)行就需要進(jìn)程和 SCM 之間建立連接并能夠響應(yīng) SCM 發(fā)出的請(qǐng)求( 正確更新?tīng)顟B(tài) ) 屁柏,要實(shí)現(xiàn)這一目的就不得不利用上面的幾個(gè)函數(shù)啦膜。比如用 sc 命令可以成功創(chuàng)建一個(gè)記事本的服務(wù),啟動(dòng)服務(wù)的時(shí)候記事本也能打開(kāi)淌喻,但因?yàn)闆](méi)法調(diào)用 StartServiceCtrlDispatcher 僧家, 30 秒之后就會(huì)被 SCM 強(qiáng)制關(guān)閉并提示啟動(dòng)失敗。
我們?nèi)粘J褂玫能浖谠O(shè)計(jì)的時(shí)候大多沒(méi)有考慮以服務(wù)的形式運(yùn)行裸删,自然就不滿足上面的接口規(guī)范八拱。如果我們非要以服務(wù)的形式運(yùn)行就需要在它們和 SCM 之間構(gòu)建一座橋梁, SCM 通過(guò)這個(gè) 第三者 來(lái)間接控制進(jìn)程,就像 Svchost 那樣肌稻。
找了幾個(gè)工具可以實(shí)現(xiàn)將任何程序注冊(cè)為 合法的 Windows 服務(wù) 清蚀。工具可以放在任何位置,不必放在系統(tǒng)目錄下灯萍,腳本在程序目錄下執(zhí)行轧铁。
RunAsSrv
最后更新時(shí)間: 2006-08-03
缺失 MSVCP71.DLL 和 MSVCR71.DLL 每聪,下載后放到 exe 同級(jí)目錄下或者安裝 微軟常用運(yùn)行庫(kù)合集 可以解決旦棉。
可能會(huì)被殺軟報(bào)病毒,介意者慎用药薯。
runassrv add /cmdline:"C:\Users\test\Desktop\nginx\nginx.exe" /name:nginx_runassrv
SrvStart
最后更新時(shí)間: 2000-06-30
很古老的工具绑洛,號(hào)稱支持 Windows NT 4 之后的所有 Windows 版本。配置項(xiàng)很多童本,文檔也不是很清楚真屯,調(diào)通有點(diǎn)費(fèi)勁。
set name=nginx_srvstart
set startup_dir=C:\Users\test\Desktop\nginx
set startup=%startup_dir%\nginx.exe
set shutdown="%startup%" -p "%startup_dir%" -s stop
:: 寫(xiě)入配置文件
(
echo [%name%]
echo startup_dir=%startup_dir%
echo startup=%startup%
echo shutdown=%shutdown%
) > nginx.ini
:: 創(chuàng)建服務(wù)
srvstart install %name% -c "%cd%\nginx.ini"
RunAsService
最后更新時(shí)間: 2020-10-01
需要安裝 .NET Framework 3.5 穷娱。官網(wǎng) 下載的不是最新的代碼绑蔫,僅支持 exe 和 com 類型的文件作為啟動(dòng)命令。
需要在管理員命令提示符中運(yùn)行泵额,否則會(huì)看不到任何信息配深。
RunAsService install "nginx_RunAsService" "C:\Users\test\Desktop\nginx\nginx.exe" -p "C:\Users\test\Desktop\nginx"
如果應(yīng)用子進(jìn)程異常關(guān)閉了會(huì)導(dǎo)致無(wú)法直接關(guān)閉服務(wù),需要手動(dòng)殺死 RunAsService.exe 進(jìn)程嫁盲。
srvany
srvany.exe 是 Microsoft Windows Resource Kits 工具集的一個(gè)實(shí)用的小工具篓叶,用于將任何 EXE 程序作為 Windows 服務(wù)運(yùn)行。
官網(wǎng)已經(jīng)找不到了羞秤,只能通過(guò)第三方下載( 參考 )缸托。支持 暫停/恢復(fù) 。
由于它只是一個(gè)服務(wù)外殼并沒(méi)有提供安裝命令瘾蛋,需要自己手動(dòng)創(chuàng)建服務(wù):
set name=nginx_srvany
set startup_dir=C:\Users\test\Desktop\nginx
set startup=%startup_dir%\nginx.exe
set "AppParameters= "
set reg_path=HKLM\SYSTEM\CurrentControlSet\services\%name%\Parameters
:: 安裝服務(wù)
sc create %name% binPath= "%cd%\srvany.exe"
:: 配置注冊(cè)表中的服務(wù)參數(shù)
reg add "%reg_path%" /f /v AppDirectory /t REG_SZ /d "%startup_dir%"
reg add "%reg_path%" /f /v Application /t REG_SZ /d "%startup%"
reg add "%reg_path%" /f /v AppParameters /t REG_SZ /d "%AppParameters%"
有人專門為它寫(xiě)了一個(gè)管理工具 SrvanyUI ( 已內(nèi)置 srvany )俐镐,還包括了對(duì)系統(tǒng)服務(wù)的管理,可以擺脫注冊(cè)表操作哺哼。
NSSM
最后更新時(shí)間: 2017-05-16
nssm is a service helper which doesn't suck. srvany and other service helper programs suck because they don't handle failure of the application running as a service.
提供了其他工具沒(méi)有的異常處理機(jī)制京革,注冊(cè)表的結(jié)構(gòu)類似于 srvany 。也可通過(guò) Chocolatey 的方式安裝幸斥, Chocolatey 中的 nginx 就是通過(guò)這種方式創(chuàng)建服務(wù)的匹摇。
nssm install nginx_nssm "C:\Users\test\Desktop\nginx\nginx.exe"
也可以使用命令打開(kāi)服務(wù)的配置界面:
nssm install nginx_nssm
winsw
Windows Service Wrapper
根據(jù)配置文件來(lái)加載安裝和啟動(dòng)配置 ,類似于 SrvStart 的升級(jí)版甲葬。 V2 版本創(chuàng)建一個(gè)服務(wù)就要復(fù)制一份程序的做法略顯笨重廊勃,在 V3 版本中增加了全局方式。
V2 版本的配置過(guò)程:
set "name=nginx_winsw"
set startup_dir=C:\Users\test\Desktop\nginx
set startup=%startup_dir%\nginx.exe
copy /y WinSW-x64.exe %name%.exe
:: 寫(xiě)入配置文件
(
echo id: %name%
echo name: ''
echo description: ''
echo executable: '"%startup%"'
echo arguments: -p "%startup_dir%"
echo stopArguments: -p "%startup_dir%" -s stop
) > %name%.yml
:: 安裝服務(wù)
%name%.exe install
整體使用下來(lái) NSSM 體驗(yàn)最好,功能多使用也方便坡垫。 winsw 也不錯(cuò)梭灿,畢竟有配置文件更適合復(fù)雜配置以及批量安裝和遷移。而 SrvanyUI 是 UI 最強(qiáng)大的冰悠,上手難度最低適合普通用戶堡妒。
此類工具畢竟需要高權(quán)限,出于安全方面考慮還是建議使用開(kāi)源項(xiàng)目溉卓。
nginx 服務(wù)
nginx 說(shuō)實(shí)話不太適合做成服務(wù)的形式皮迟,管理起來(lái)也比較麻煩,而且上面的工具中除了 NSSM 和 SrvStart 外都不能正常關(guān)閉服務(wù)桑寨,不是進(jìn)程沒(méi)殺全就是其他的異常伏尼。我更喜歡的做法:
把快捷方式丟到開(kāi)始菜單的啟動(dòng)項(xiàng)(
shell:startup
)中用于開(kāi)機(jī)啟動(dòng)。-
再建兩個(gè)快捷方式改參數(shù)丟到任務(wù)欄工具欄中用于關(guān)閉和重啟:
:: 關(guān)閉 nginx -s stop :: 重啟 nginx -s reload
C# 編寫(xiě)服務(wù)程序
這里演示如何在 Visual Studio 中創(chuàng)建可向事件日志中寫(xiě)入消息的 Windows 服務(wù)應(yīng)用程序尉尾。( 如何調(diào)試 )
具體步驟可以看 微軟文檔 爆阶,只是機(jī)翻的文檔很別扭,我重新整理了一下沙咏。
在 .NET 5.0 SDK 或更高版本 中可以使用 BackgroundService 創(chuàng)建 Windows 服務(wù)辨图。( demo )
下載安裝 Visual Studio
新版安裝程序還是很清爽的,按需選擇肢藐,不像以前那樣一股腦安裝各種不需要的東西故河,太占空間了。
只是為了測(cè)試窖壕,勾選 .NET 桌面開(kāi)發(fā) 即可忧勿,安裝占用空間( 不壓縮 C 盤 )大概 7.36 G 。
新建項(xiàng)目
以 管理員權(quán)限 運(yùn)行 VS 并新建項(xiàng)目 WindowsServiceTest 瞻讽。
語(yǔ)言選擇 C# 鸳吸,平臺(tái)選擇 Windows ,選中 Windows 服務(wù) 模板速勇。( 可直接搜索 )
.NET Framework 4.7.2
修改代碼
在 解決方案資源管理器 中晌砾,選擇默認(rèn)創(chuàng)建的 Service1.cs 右鍵重命名( F2
)為 MyNewService.cs 并 切換到代碼視圖 。
-
Program.cs
using System.ServiceProcess; namespace WindowsServiceTest { internal static class Program { /// <summary> /// 應(yīng)用程序的主入口點(diǎn)烦磁。 /// </summary> static void Main(string[] args) { ServiceBase[] ServicesToRun = new ServiceBase[] { new MyNewService(args) }; ServiceBase.Run(ServicesToRun); } } }
-
MyNewService.cs
設(shè)置屬性 CanPauseAndContinue 是為了啟用 暫停/恢復(fù) 功能养匈,可以在 屬性 窗口直接設(shè)置,這里直接寫(xiě)死在初始化代碼里都伪。
修改 ServiceName 屬性值為 MyNewService ( 可選 )
注意有兩個(gè)參數(shù):一個(gè)是構(gòu)造方法中的初始化參數(shù)呕乎,另一個(gè)是 OnStart 方法中的啟動(dòng)參數(shù)。
using System; using System.Diagnostics; using System.ServiceProcess; using System.Timers; namespace WindowsServiceTest { public partial class MyNewService : ServiceBase { private readonly EventLog eventLog; private Timer timer; private int eventId = 1; public MyNewService(string[] args) { InitializeComponent(); CanPauseAndContinue = true; eventLog = new EventLog(); if (!EventLog.SourceExists("MySource")) { EventLog.CreateEventSource("MySource", "MyNewLog"); } eventLog.Source = "MySource"; eventLog.Log = "MyNewLog"; eventLog.WriteEntry("Init: " + string.Join(",", args)); } protected override void OnStart(string[] args) { eventLog.WriteEntry("In OnStart: " + string.Join(",", args)); // Set up a timer that triggers every minute. timer = new Timer(); timer.Interval = 60000; // 60 seconds timer.Elapsed += new ElapsedEventHandler(this.OnTimer); timer.Start(); } public void OnTimer(object sender, ElapsedEventArgs args) { eventLog.WriteEntry("Monitoring the System", EventLogEntryType.Information, eventId++); } protected override void OnStop() { eventLog.WriteEntry("In OnStop."); } protected override void OnPause() { timer.Stop(); eventLog.WriteEntry("In OnPause."); } protected override void OnContinue() { timer.Start(); eventLog.WriteEntry("In OnContinue."); } } }
生成服務(wù)程序
在 解決方案資源管理器 中陨晶,右鍵項(xiàng)目名選擇 生成 猬仁。( Ctrl + B
)
已啟動(dòng)生成…
1>------ 已啟動(dòng)生成: 項(xiàng)目: WindowsServiceTest, 配置: Debug Any CPU ------
1> WindowsServiceTest -> C:\Users\test\source\repos\WindowsServiceTest\WindowsServiceTest\bin\Debug\WindowsServiceTest.exe
========== 生成: 成功 1 個(gè),失敗 0 個(gè),最新 0 個(gè)湿刽,跳過(guò) 0 個(gè) ==========
生成的 exe 文件默認(rèn)是不能直接運(yùn)行的( 可以修改 )的烁,需要注冊(cè)為服務(wù)才行。
安裝服務(wù)
可以使用通用的 sc 命令進(jìn)行注冊(cè)诈闺,就是詳細(xì)配置會(huì)繁瑣一點(diǎn)渴庆。
:: 注意等號(hào)與值中間有個(gè)空格
sc create MyNewServiceSC binpath= "C:\Users\test\source\repos\WindowsServiceTest\WindowsServiceTest\bin\Debug\WindowsServiceTest.exe"
也可以按教程中的方法:
添加安裝程序
在 解決方案資源管理器 中,右鍵服務(wù)名( MyNewService.cs ) 查看設(shè)計(jì)器 雅镊,在 設(shè)計(jì)器 窗口中右鍵 添加安裝程序 襟雷。
修改執(zhí)行用戶
選中 serviceProcessInstaller1 ,在 屬性 中修改 Account 為 LocalSystem 漓穿。
這個(gè)就是任務(wù)管理器中看到的進(jìn)程所屬的用戶嗤军,涉及到權(quán)限的問(wèn)題注盈。( 參考 )
修改服務(wù)配置( 可選 )
選中 serviceInstaller1 晃危,在 屬性 中修改服務(wù)名稱、顯示名稱老客、描述等僚饭。
不修改就是默認(rèn)的 Service1 。
重新生成服務(wù)程序( Ctrl + B
)使安裝配置生效胧砰。
打開(kāi) 開(kāi)發(fā)者命令提示
執(zhí)行安裝命令
cd WindowsServiceTest\bin\Debug
:: 需要管理員權(quán)限
installutil WindowsServiceTest.exe
:: 卸載
installutil.exe /u WindowsServiceTest.exe
啟動(dòng)服務(wù)
任務(wù)管理器 > 服務(wù) > 隨便選中一個(gè)服務(wù)右鍵 > 打開(kāi)服務(wù)
驗(yàn)證結(jié)果
Win + X
> 事件查看器 > 應(yīng)用程序和服務(wù)日志 > MyNewLog
看不到 MyNewLog 需要先啟動(dòng)服務(wù)后再重新打開(kāi) 事件查看器 鳍鸵。
因?yàn)橥ㄓ眠壿嫸挤庋b在 ServiceBase 里面了,只需要添加自己的業(yè)務(wù)代碼尉间,比起 C++ 實(shí)現(xiàn)的 demo 要簡(jiǎn)單很多偿乖。編寫(xiě) 多線程服務(wù) 或者復(fù)雜應(yīng)用時(shí)可能會(huì)遇到一些問(wèn)題( 參考 )。
參考文章
- 了解 Windows 服務(wù)體系結(jié)構(gòu)
- 后臺(tái)服務(wù)程序開(kāi)發(fā)模式
- 用 C 語(yǔ)言編寫(xiě) Windows 服務(wù)程序的五個(gè)步驟
- Windows 操作系統(tǒng)的體系結(jié)構(gòu)
- Windows 服務(wù)編寫(xiě)原理及探討 (1) 哲嘲、 (2) 贪薪、 (3) 、 (4)
- 解決“指定的服務(wù)已經(jīng)標(biāo)記為刪除”問(wèn)題
結(jié)語(yǔ)
以上內(nèi)容是我根據(jù)日常使用經(jīng)驗(yàn)再結(jié)合有限的資料整理而成眠副,難免有錯(cuò)誤的地方画切,歡迎指正。相關(guān)內(nèi)容比較多囱怕,全部引用太占篇幅了霍弹,感興趣的話就多點(diǎn)點(diǎn)文中給出的外鏈。