@SERVICE, unexpected results

May 20, 2008
9,839
69
Syracuse, NY, USA
@SERVICE seems better that it was, but it gives unexpected results.

For info level 3, it always returns 0. I tried about a dozen services, many of which I know can be stopped.

For info level 4, it sometimes gives values that seem rather large (spooler = 69, diskeeper = 65, eventlog = 4).

For info level 5, it always returns 0, which I suppose could be correct. But I know from experience that these operations don't happen instantly. OTOH, if the SCM asks the service for the estimate, the service itself might not bother to give a meaningful one.
 
May 20, 2008
9,839
69
Syracuse, NY, USA
Actually it seems you just have the indices for ControlsAccepted and CheckPoint switched, either in the help or in the code.

For spooler, %SERVICE gives:

Code:
for /L %i in (1,1,5) echo %@service[spooler,%i]
272
4
0
69
0
while,

Code:
wprintf(L"Name\t%s\n"
        L"Type\t%lu\n"
        L"State\t%lu\n"
        L"Control\t%lu\n"
        L"CheckPt\t%lu\n"
        L"Wait\t%lu\n",
        argv[1],
        ssp.dwServiceType,
        ssp.dwCurrentState,
        ssp.dwControlsAccepted,
        ssp.dwCheckPoint,
        ssp.dwWaitHint);
gives:

Code:
Name    spooler
Type    272
State   4
Control 69
CheckPt 0
Wait    0
 
May 20, 2008
9,839
69
Syracuse, NY, USA
I wrote:

Actually it seems you just have the indices for ControlsAccepted and CheckPoint switched, either in the help or in the code.
When looking at the SERVICE_STATUS_PROCESS struct (9 DWORDs) for the first time, I thought ... why not let the user specify any index (0-8) and let @SERVICE act thus:

Code:
    SERVICE_STATUS_PROCESS ssp;

    if ( QueryServiceStatusEx(..., (LPBYTE) &ssp, ...) )

        Sprintf(pszArgs, L"%lu", *((LPDWORD) &ssp + index));
That might simplify the code and provide the user with additional useful info (dwWin32ExitCode, dwServiceSpecificExitCode, dwProcessId, and dwServiceFlags). The help already documents the hard ones. :-)
 

rconn

Administrator
Staff member
May 14, 2008
11,416
107
vefatica wrote:

> @SERVICE seems better that it was, but it gives unexpected results.
>
> For info level 3, it always returns 0. I tried about a dozen services, many of which I know can be stopped.
>
> For info level 4, it sometimes gives values that seem rather large (spooler = 69, diskeeper = 65, eventlog = 4).
3 and 4 are reversed in the help; the help has been corrected for the
next build.


> For info level 5, it always returns 0, which I suppose could be correct. But I know from experience that these operations don't happen instantly. OTOH, if the SCM asks the service for the estimate, the service itself might not bother to give a meaningful one.
You'll have to argue with MS on that one; @SERVICES is just returning
what the EnumServicesStatus API says.

Rex Conn
JP Software
 

rconn

Administrator
Staff member
May 14, 2008
11,416
107
vefatica wrote:

> When looking at the SERVICE_STATUS_PROCESS struct (9 DWORDs) for the first time, I thought ... why not let the user specify any index (0-8) and let @SERVICE act thus:
> ---------
> SERVICE_STATUS_PROCESS ssp;
>
> if ( QueryServiceStatusEx(..., (LPBYTE) &ssp, ...) )
>
> Sprintf(pszArgs, L"%lu", *((LPDWORD) &ssp + index));
> ---------
> That might simplify the code and provide the user with additional useful info (dwWin32ExitCode, dwServiceSpecificExitCode, dwProcessId, and dwServiceFlags). The help already documents the hard ones. :-)
I've never seen a service that set (or documented) dwWin32ExitCode or
dwServiceSpecificExitCode, so unless you were writing your own service
those would probably be useless.

@SERVICES uses SERVICE_STATUS, not SERVICE_STATUS_PROCESS, so there is
no dwProcessId or dwServiceFlags. (I can't think of a use for them --
why would you care about those values?)

Rex Conn
JP Software
 
May 20, 2008
9,839
69
Syracuse, NY, USA
On Mon, 18 May 2009 22:47:54 -0500, rconn <> wrote:

|@SERVICES uses SERVICE_STATUS, not SERVICE_STATUS_PROCESS, so there is
|no dwProcessId or dwServiceFlags. (I can't think of a use for them --
|why would you care about those values?)

I can't imagine a use for @SERVICE at all. But I suppose someone has/will. But
I'd think the PID of the process it's running in (not obvious without
"...\system32\tasklist /svc") might be of interest to someone using @SERVICE at
all.

I suppose dwWin32ExitCode is the EXE's exit code (service or svchost) while
dwServiceSpecificExitCode can be set by a service DLL. I write my own; have
used my w32tm.dll as a replacement for w32time.dll for years. It sets
dwServiceSpecificExitCode, to 0 typically, but to non-zero if it can't
initialize.
--
- Vince
 
May 20, 2008
9,839
69
Syracuse, NY, USA
Code:
SERVICE_STATUS_PROCESS ssp;

if ( QueryServiceStatusEx(..., (LPBYTE) &ssp, ...) )

    Sprintf(pszArgs, L"%lu", *((LPDWORD) &ssp + index));
Just in case you wanted to go that route, I made a corresponding f_service.htm. It's attached.

The HTML editor from VS2008 wasn't much fun ... got a recommendation?
 

Attachments