我寫了一個小服務,它充當本地網絡服務器。要編寫服務,我遵循tutorial on MSDN,如何使用ServiceBase
類編寫服務。服務導致SCM錯誤「報告無效當前狀態0」
但是當我註冊並啓動服務時,我收到如下所示的錯誤消息。在開始和停止服務時,我收到了兩條錯誤消息。 (示例=服務的名稱)。
示例服務報告了一個無效的當前狀態0
這裏我服務的最少的樣品與所有相關零件。代碼開頭這是在MSDN教程中提供一個枚舉和結構定義:
public enum ServiceState
{
SERVICE_STOPPED = 0x00000001,
SERVICE_START_PENDING = 0x00000002,
SERVICE_STOP_PENDING = 0x00000003,
SERVICE_RUNNING = 0x00000004,
SERVICE_CONTINUE_PENDING = 0x00000005,
SERVICE_PAUSE_PENDING = 0x00000006,
SERVICE_PAUSED = 0x00000007,
}
[StructLayout(LayoutKind.Sequential)]
public struct ServiceStatus
{
public long dwServiceType;
public ServiceState dwCurrentState;
public long dwControlsAccepted;
public long dwWin32ExitCode;
public long dwServiceSpecificExitCode;
public long dwCheckPoint;
public long dwWaitHint;
};
在此之後,該服務代碼我寫的,減少到相關部分:
namespace example
{
public partial class Service : ServiceBase
{
public Service()
: base()
{
this.ServiceName = "ExampleService";
this.AutoLog = false;
this.CanStop = true;
this.CanShutdown = false;
this.CanPauseAndContinue = false;
this.CanHandlePowerEvent = false;
this.CanHandleSessionChangeEvent = false;
}
protected override void OnStart(string[] args)
{
try {
SetServiceState(ServiceState.SERVICE_START_PENDING, 100000);
// ... initialise and start...
SetServiceState(ServiceState.SERVICE_RUNNING);
} catch (System.Exception ex) {
SetServiceState(ServiceState.SERVICE_STOPPED);
}
}
protected override void OnStop()
{
SetServiceState(ServiceState.SERVICE_STOP_PENDING, 100000);
// ... stop service ...
SetServiceState(ServiceState.SERVICE_STOPPED);
}
private void SetServiceState(ServiceState state, int waitHint = 0)
{
ServiceStatus serviceStatus = new ServiceStatus();
serviceStatus.dwCurrentState = state;
serviceStatus.dwWaitHint = waitHint;
SetServiceStatus(this.ServiceHandle, ref serviceStatus);
}
[DllImport("advapi32.dll", SetLastError=true)]
private static extern bool SetServiceStatus(IntPtr handle, ref ServiceStatus serviceStatus);
}
}
的主入口點很簡單,因爲這:
static void Main(string[] args)
{
ServiceBase.Run(new Service());
}
正如你所看到的,錯誤信息的數量相匹配的SetServiceState
呼叫的數量。如果我添加其他此類調用,錯誤消息的數量會相應增加。
因此,我認爲,整個問題在我調用SetServiceStatus
API的方式中,但我目前看不到問題。
你能發現問題嗎?
無論如何,這是使用C#和.NET構建服務的正確方法嗎?
太好了,謝謝,這解決了這個問題。我通常意識到MSDN文檔有多糟糕,但在這裏我只是假設這個例子中的結構定義是正確的。你也是對的,手動狀態更新並不是必須的。我的代碼的啓動在第一個版本中花了很長時間,但是我將所有內容都移到了一個線程中,因爲這些長進程的結果與啓動無關。偉大的博客條目,只是逐步列表的格式讓我幾乎感到頭痛;-)。 – Flovdis
太棒了,它爲我工作。這是不可能的計算MSDN有多少錯誤....這是無限數量之一... – Fabiano
非常感謝,Rainer - 我使用微軟的示例代碼來創建一個服務,並直接打這個問題。我還在此處爲他們的頁面添加了一條評論(https://technet.microsoft.com/en-us/library/cc756305(v=ws.10).aspx),指向您的解決方案。 – Rich