@SERVICE, unexpected results

#1
@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.
 
#2
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
 
#3
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
10,770
97
#4
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
10,770
97
#5
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
 
#6
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
 
#7
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