views:

109

answers:

2

I get a running status for both starting and started state using ServiceControllerStatus. Is there any way to find whether the service has been completely started

+1  A: 

Yes, but it is a little ugly:

Import ADVAPI32.DLL:

[DllImport ("advapi32.dll", EntryPoint = "QueryServiceStatus", CharSet = CharSet.Auto)]
internal static extern bool QueryServiceStatus (IntPtr hService, ref SERVICE_STATUS dwServiceStatus);

declare some structs:

[StructLayout(LayoutKind.Sequential)]
public struct SERVICE_STATUS
{
    public int serviceType;
    public int currentState;
    public int controlsAccepted;
    public int win32ExitCode;
    public int serviceSpecificExitCode;
    public int checkPoint;
    public int waitHint;
}

public enum State
{
    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,
}

EDIT: Easier to user QueryServiceStatus(), but in general it remains the same. See the links for details, I don't think it is helpful if I paste that much code here.

Then you can use the ControlService with control code SERVICE_CONTROL_INTERROGATE to issue status information requests.

See http://msdn.microsoft.com/en-us/library/ms682108(VS.85).aspx

http://www.pinvoke.net/default.aspx/advapi32.ControlService

mnemosyn
+3  A: 

The ServiceController.Status() property already uses the native QueryServiceStatus() API function. It will return ServiceControllerStatus.StartPending if the service returns the SERVICE_START_PENDING status code.

You'll have to take the return value as-is, the service is in complete control of its status codes. If you never get StartPending then the service most likely just doesn't require any time to get started. Which is fairly common. If you find the service to be unresponsive for a while, even though you got the Running status back then there's a flaw in the service implementation.

Hans Passant
+1: I just want to add that most times when I call ServiceController.Refresh() method before checking the status, it gives me the correct status.
Sameh Serag
+1 Sounds more convincing than what I wrote - I didn't know how the managed API is implemented internally. I also didn't really really understand the OP's issue...I will now code more. And learn. The dude abides :)
mnemosyn
@mnemosyn: Far from it, your original insight is very valuable. There is no mystique to managed code, the Windows API invariable provides only one way to get the job done. The 99% case is that managed code does the exact same thing that unmanaged code can do. If managed code misbehaves, you can only really diagnose it by trying to guess how the unmanaged API misbehaves. Only the exceptions are better.
Hans Passant