Tôi đã viết một dịch vụ nhỏ, hoạt động như một máy chủ mạng cục bộ. Để viết dịch vụ, tôi đã theo dõi tutorial on MSDN, cách viết dịch vụ bằng cách sử dụng lớp ServiceBase
.Dịch vụ gây ra lỗi SCM "báo cáo trạng thái hiện tại không hợp lệ 0"
Nhưng khi tôi đăng ký và bắt đầu dịch vụ, tôi nhận được thông báo lỗi như được hiển thị bên dưới. Tôi nhận được chính xác hai thông báo lỗi này lúc bắt đầu và tại điểm dừng dịch vụ. (Ví dụ = tên dịch vụ).
Các dịch vụ Ví dụ đã thông báo tình trạng hiện thời không hợp lệ 0.
Dưới đây là một mẫu tối thiểu của các dịch vụ của tôi với tất cả các bộ phận liên quan. Mã này bắt đầu với một định nghĩa enum và struct được cung cấp trong hướng dẫn 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;
};
Sau đó, các mã dịch vụ tôi đã viết, giảm đến các bộ phận có liên quan:
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);
}
}
các điểm nhập cảnh chính là đơn giản như thế này:
static void Main(string[] args)
{
ServiceBase.Run(new Service());
}
như bạn có thể thấy, số lượng các thông báo lỗi phù hợp với số SetServiceState
cuộc gọi. Nếu tôi thêm các cuộc gọi như vậy, số lượng thông báo lỗi sẽ tăng lên tương ứng.
Vì vậy, tôi giả sử, toàn bộ vấn đề là một nơi nào đó theo cách tôi gọi API SetServiceStatus
, nhưng hiện tại tôi không thể thấy sự cố.
Bạn có thể phát hiện sự cố không?
Dù sao đây có phải là cách chính xác để xây dựng Dịch vụ bằng C# và .NET không?
Tuyệt vời, cảm ơn bạn, điều này đã giải quyết được vấn đề. Tôi thường biết làm thế nào xấu tài liệu MSDN là, nhưng ở đây tôi chỉ giả định định nghĩa cấu trúc này từ ví dụ là chính xác. Bạn cũng đúng, các cập nhật trạng thái thủ công không thực sự cần thiết. Việc khởi động mã của tôi mất một thời gian dài trong phiên bản đầu tiên, nhưng tôi đã chuyển mọi thứ trong một luồng, bởi vì kết quả của một số quy trình dài này không liên quan đến việc khởi động. Great blog entry, chỉ cần định dạng của danh sách từng bước đã cho tôi gần như nhức đầu ;-). – Flovdis
Tuyệt vời, nó làm việc cho tôi. Không thể đếm được bao nhiêu lỗi MSDN có .... đây là một trong số vô hạn ... – Fabiano
Cảm ơn rất nhiều, Rainer - Tôi đã sử dụng mã mẫu của Microsoft để tạo một dịch vụ và nhấn chính xác vấn đề này ngay lập tức. Tôi cũng đã thêm một bình luận vào trang của họ ở đây (https://technet.microsoft.com/en-us/library/cc756305(v=ws.10).aspx) trỏ đến giải pháp của bạn ở đây. – Rich