1053 The service did not respond to the start or control request in a timely fashion 錯誤1053:服務沒有及時響應啟動或控制請求


Windows 服務應用程序介紹 | Microsoft Docs https://docs.microsoft.com/zh-cn/dotnet/framework/windows-services/introduction-to-windows-service-applications

 

Microsoft Windows 服務(過去稱為 NT 服務)允許用戶創建可在其自身的 Windows 會話中長時間運行的可執行應用程序。 這些服務可在計算機啟動時自動啟動,可以暫停和重啟,並且不顯示任何用戶界面。 這些功能使服務非常適合在服務器上使用,或者需要長時間運行的功能(不會影響在同一台計算機上工作的其他用戶)的情況。 還可以在與登錄用戶或默認計算機帳戶不同的特定用戶帳戶的安全性上下文中運行服務。 有關服務和 Windows 會話的詳細信息,請參閱 Windows SDK 文檔。

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

可以將服務創建為 Microsoft Visual Studio 項目,並在其中定義代碼,以控制可以將哪些命令發送到服務以及在收到這些命令時應采取的操作。 可以發送到服務的命令包括啟動、暫停、恢復和停止服務,還可以執行自定義命令。

在創建和生成應用程序之后,可以通過運行命令行實用程序 InstallUtil.exe 並將該路徑傳遞給服務的可執行文件來安裝它。 然后,可以使用服務控制管理器 來啟動、停止、暫停、恢復和配置服務。 還可以在“服務器資源管理器” 的“服務” 節點中或使用 ServiceController 類完成許多相同的任務。

服務應用程序與其他 Visual Studio 應用程序

服務應用程序與許多其他項目類型的運行方式存在以下幾個方面的不同:

  • 在項目能夠以有意義的方式運行之前,服務應用程序項目創建的已編譯可執行文件必須安裝在服務器上。 無法通過按 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),可以在其中定義在服務更改狀態時執行的其他處理進程。

服務類型

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

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

服務和 ServiceController 組件

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

有關詳細信息,請參閱 ServiceController

要求

  • 必須在 Windows 服務 應用程序項目或其他 .NET Framework(啟用了在生成並從 ServiceBase 類繼承時創建 .exe 文件的項目)中創建服務。

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

請參閱

 

 

從注冊表刪除服務項。

C:\>sc delete
描述:
從注冊表刪除服務項。
如果服務正在運行,或另一進程已經打開
到此服務的句柄,服務將簡單地標記為
刪除。
用法:
sc <server> delete [service name]

 

Golang 實現Windows服務_Ango_的專欄-CSDN博客_golang windows 服務 https://blog.csdn.net/ango_/article/details/104161896

 

什么是windows服務
Windows 服務是主要用於服務器環境而長期運行的應用程序, 這類程序不需要有用戶界面或者任何模擬輸出。 任何的用戶消息通常都是記錄在Windows 事件日志里。Windows Service可以在操作系統啟動的時候開始,一直在后台運行,當有需要時也可以手動啟動,我們可以通過管理工具里面的服務進行統一管理。
當系統啟動完畢后,Windows服務並不需要通過登陸頁面后才能啟動,即使用戶注銷登錄也不會停止,通常不和用戶產生交互。
而我們啟動一般的exe文件卻要先登陸Windows后才能啟動它,通常還有一個用戶界面,命令行或者是GUI界面,通常由用戶手動啟動和停止。

如何注冊windows服務
手工注冊Windows服務得用得到windows下cmd命令(管理員身份)
注冊服務 [ServiceTest]:

sc create ServiceTest binpath="/path/to/exe"
1
啟動服務:

sc start ServiceTest
1
停止服務、刪除服務:

sc stop ServiceTest
sc delete ServiceTest
1
2
用vc++實現windows服務:
首先要初始化 SERVICE_TABLE_ENTRY 結構體數組,

SERVICE_TABLE_ENTRY serviceEntryTable[2];
serviceEntryTable[0].lpServiceName = L"ServiceTest";
serviceEntryTable[0].lpServiceProc = (LPSERVICE_MAIN_FUNCTION)ServiceWorker;
serviceEntryTable[1].lpServiceName = NULL;
serviceEntryTable[1].lpServiceProc = NULL;

其中,ServiceTest 是要注冊的服務的名稱,ServiceWorker 是服務主工作函數。
通過調用 StartServiceCtrlDispatcher(serviceEntryTable),把調用進程的主線程轉換為控制分派器,啟動一個新線程運行分派表中的 ServiceWorker 函數。

然后,准備ServiceWorker函數,
ServiceWorker 服務程序的主運行函數,除了與普通函數執行任務之外,
它還需要完成一個工作:通過調用 RegisterServiceCtrlHandler向服務控制管理器注冊控制函數。
並且調用 向 SCM(服務控制管理器)報告當前的狀態。

SERVICE_STATUS serviceStatus;
serviceStatus.dwServiceType = SERVICE_WIN32;
serviceStatus.dwCurrentState = SERVICE_START_PENDING;
serviceStatus.dwControlsAccepted = SERVICE_ACCEPT_SHUTDOWN | SERVICE_ACCEPT_STOP;
serviceStatus.dwWin32ExitCode = 0;
serviceStatus.dwServiceSpecificExitCode = 0;
serviceStatus.dwCheckPoint = 0;
serviceStatus.dwWaitHint = 0;
serviceStatusHandle = ::RegisterServiceCtrlHandler(L"ServiceTest", ServiceCtrlHandler);

其中 ServiceCtrlHandler是控制處理函數,它接收 SCM 發來的控制命令,並且處理命令和回饋狀態。

最后,准備控制處理函數 ServiceCtrlHandler
控制處理函數必須在30秒內返回,否則 SCM 會返回一個錯,如果是一個比較耗時的操作,則需要另啟一個線程來進行處理。

void WINAPI ServiceCtrlHandler(DWORD request)
{
switch (request)
{
case SERVICE_CONTROL_STOP:
serviceRunning = false;
serviceStatus.dwCurrentState = SERVICE_STOPPED;
break;
case SERVICE_CONTROL_SHUTDOWN:
serviceRunning = false;
serviceStatus.dwCurrentState = SERVICE_STOPPED;
break;
default:
break;
}
SetServiceStatus(serviceStatusHandle, &serviceStatus);
}
 
完整示例代碼
該示例實現了一個簡單的windows服務程序,
每秒鍾在C盤目錄下打印一個數字。

#include <string>
#include <fstream>
#include <iostream>
#include <windows.h>

using namespace std;

bool serviceRunning = false;
SERVICE_STATUS serviceStatus;
SERVICE_STATUS_HANDLE serviceStatusHandle;

void WINAPI ServiceWorker(int argc, char** argv);
void WINAPI ServiceCtrlHandler(DWORD request);


void ServiceLog(string str)
{
fstream fout("c:/service_log.txt", ios::out | ios::app);
if (!fout) {
return;
}
fout << str << endl;
}

void WINAPI ServiceWorker(int argc, char** argv)
{
serviceStatus.dwServiceType = SERVICE_WIN32;
serviceStatus.dwCurrentState = SERVICE_START_PENDING;
serviceStatus.dwControlsAccepted = SERVICE_ACCEPT_SHUTDOWN | SERVICE_ACCEPT_STOP;
serviceStatus.dwWin32ExitCode = 0;
serviceStatus.dwServiceSpecificExitCode = 0;
serviceStatus.dwCheckPoint = 0;
serviceStatus.dwWaitHint = 0;

serviceStatusHandle = ::RegisterServiceCtrlHandler(L"ServiceTest", ServiceCtrlHandler);

if (0 == serviceStatusHandle)
{
ServiceLog("RegisterServiceCtrlHandler failed");
return;
}

ServiceLog("RegisterServiceCtrlHandler success");

serviceStatus.dwCurrentState = SERVICE_RUNNING;
SetServiceStatus(serviceStatusHandle, &serviceStatus);

// 工作內容,每隔一秒鍾輸出一個數字
int num = 0;
serviceRunning = true;
while (serviceRunning)
{
ServiceLog(to_string(num++));
Sleep(1000);
}
ServiceLog("Service Stopped");
}

void WINAPI ServiceCtrlHandler(DWORD request)
{
switch (request)
{
case SERVICE_CONTROL_STOP:
serviceRunning = false;
serviceStatus.dwCurrentState = SERVICE_STOPPED;
break;

case SERVICE_CONTROL_SHUTDOWN:
serviceRunning = false;
serviceStatus.dwCurrentState = SERVICE_STOPPED;
break;

default:
break;
}

SetServiceStatus(serviceStatusHandle, &serviceStatus);
}

void main()
{
SERVICE_TABLE_ENTRY serviceEntryTable[2];
serviceEntryTable[0].lpServiceName = L"ServiceTest";
serviceEntryTable[0].lpServiceProc = (LPSERVICE_MAIN_FUNCTION)ServiceWorker;
serviceEntryTable[1].lpServiceName = NULL;
serviceEntryTable[1].lpServiceProc = NULL;

StartServiceCtrlDispatcher(serviceEntryTable);
}
 
Golang 實現 Windows 服務
Go語言有第三方封裝好的庫,可以用很少的代碼實現一個Windows服務,相比C++方便了很多。

package main

import (
"log"
"os"
"time"
"github.com/kardianos/service"
)

type program struct{}

func (p *program) Start(s service.Service) error {
go p.run()
return nil
}

func (p *program) run() {
for {
time.Sleep(time.Second)
log.Println("running")
}
}

func (p *program) Stop(s service.Service) error {
return nil
}

func init() {
f, err := os.Create("d:/gowinservice.txt")
if err != nil {
log.Fatal(err)
}
log.SetOutput(f)
}

func main() {
svcConfig := &service.Config{
Name: "GoService",
DisplayName: "GoServiceDis",
Description: "windows service form golang",
}

prg := &program{}
s, err := service.New(prg, svcConfig)
if err != nil {
log.Fatal(err)
}

if len(os.Args) > 1 {
if os.Args[1] == "install" {
s.Install()
log.Println("服務安裝成功")
return
}

if os.Args[1] == "remove" {
s.Uninstall()
log.Println("服務卸載成功")
return
}
}

if err = s.Run(); err != nil {
log.Fatal(err)
}
}

 

 

服務啟動不了(ERROR:1053)的解決方法_x3230835的博客-CSDN博客 https://blog.csdn.net/x3230835/article/details/46313203

 

Error 1053:The service did not respond to the start or control request in a timely fashion”(錯誤 1053:服務沒有及時響應啟動或控制請求)錯誤信息”

protected override void OnStart( string[] args )
{
while(true){;}
}

一般是OnStart中有死循環,服務管理器沒有檢測到啟動完成,超過一段時間后就會報錯

解決方法:

把處理函數放在線程中


protected override void OnStart( string[] args )
{
th = new Thread( new ParameterizedThreadStart( Start ) );
th.Start( null );
}

private void Start( object obj )
{
while(true){;}
}

別忘了為OnStop回收th

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM