问题
I am calling the Win32 API from .Net 1.1 to request additional startup time for a service (.Net 2.0 and up is not an option currently). Here is the pseudo-code I am calling within the OnStart() method.
private void OnStart(){
private IntPtr statusHandle;
private IntPtr serviceHandle;
private IntPtr serviceControlManagerHandle;
serviceControlManagerHandle = ServiceUtil.OpenSCManager(null, null, (uint)ServiceUtil.SCM_ACCESS.SC_MANAGER_ALL_ACCESS);
serviceHandle = ServiceUtil.OpenService(serviceControlManagerHandle, this.ServiceName, (uint)ServiceUtil.SERVICE_ACCESS.SERVICE_ALL_ACCESS);
//This fills the empty object with VALID data
SERVICE_STATUS status = ServiceUtil.QueryServiceStatus(serviceHandle, ref status)
//This returns a VALID pointer.
statusHandle = ServiceUtil.RegisterServiceCtrlHandler(this.ServiceName, serviceHandle);
}
This part works just fine. I receive valid (non IntPtr.Zero) handles for each and I can update the SERVICE_STATUS just fine. However, I REALLY need this code to be in the Init() method (I am retrofitting a legacy service that is timing out). But when I move this code to the Init() method, I can get a valid handle to the Service Control Manager and the Service itself, but NOT the Service Status. My resulting, NON-WORKING, code appears as follows...
private void MyServiceClass(){
InitializeComponent();
private IntPtr statusHandle;
private IntPtr serviceHandle;
private IntPtr serviceControlManagerHandle;
serviceControlManagerHandle = ServiceUtil.OpenSCManager(null, null, (uint)ServiceUtil.SCM_ACCESS.SC_MANAGER_ALL_ACCESS);
serviceHandle = ServiceUtil.OpenService(serviceControlManagerHandle, this.ServiceName, (uint)ServiceUtil.SERVICE_ACCESS.SERVICE_ALL_ACCESS);
statusHandle = ServiceUtil.RegisterServiceCtrlHandler(this.ServiceName, serviceHandle);
//This fills the empty object with VALID data
SERVICE_STATUS status = ServiceUtil.QueryServiceStatus(serviceHandle, ref status)
//This returns an INVALID pointer.
statusHandle = ServiceUtil.RegisterServiceCtrlHandler(this.ServiceName, serviceHandle);
}
In BOTH cases, QueryServiceStatus fills "status" with valid values. However, only the first example sets "statusHandle" to a valid pointer. How can I get a valid handle to the service's status struct before entering the OnStart() method?
回答1:
If the RegisterServiceCtrlHandlerEx function, which is most likely the one invoked by the ServiceUtil.RegisterServiceCtrlHandler
method, fails it will return an empty pointer.
Try invoking the GetLastError function to get back the details about what went wrong. My guess is that it's a timing issue. The service itself may simply not be ready to accept handler functions during initialization.
What exactly are you trying to achieve? We might be able to work out a different solution.
来源:https://stackoverflow.com/questions/8389670/get-service-status-handle-after-initializing-service