How to start a service programmatically

I have a service app, which I'm able to install with no problem, but I can't figure out how to start it without having to go to the windows Service menu.

I had code to do this before, but my repository hard drive recently went bad, and I've lost all my example code.

How can I programmatically start a service application?
LVL 30
AxterAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

jkrCommented:
The idea is to

void    StartService        (   LPCTSTR             pszName,
                                int                 argc,
                                const wchar_t**     argv
                            )
{
    SC_HANDLE   schService;
    SC_HANDLE   schSCManager;

    schSCManager    =   OpenSCManager   (   NULL,                   // machine (NULL == local)
                                            NULL,                   // database (NULL == default)
                                            SC_MANAGER_ALL_ACCESS   // access required
                                        );
    if  (   schSCManager)
        {
            schService  =   OpenService (   schSCManager,
                                            pszName,
                                            SERVICE_ALL_ACCESS
                                        );

            if  (   schService)
                {
                    // try to start the service
                    if  (   StartService    (   schService,
                                                argc,
                                                argv
                                            )
                        )
                        {
                            wprintf (   TEXT    (   "Starting %s."),
                                        pszName
                                    );

                            Sleep   (   1000 );

                            while   (   QueryServiceStatus  (   schService,
                                                                &g_ssStatus
                                                            )
                                    )
                                    {
                                        if  (       SERVICE_START_PENDING  
                                                ==  g_ssStatus.dwCurrentState
                                            )
                                            {
                                                wprintf (   TEXT    (   "."));
                                                Sleep( 1000 );
                                            }
                                        else
                                                break;
                                    }

                            if  (   SERVICE_RUNNING ==  g_ssStatus.dwCurrentState)
                                    wprintf (   TEXT    (   "\n%s started.\n"),
                                                pszName
                                            );
                            else
                                    wprintf (   TEXT    (   "\n%s failed to start.\n"),
                                                pszName
                                            );

                        }

                CloseServiceHandle  (   schService);
            }
            else
                wprintf (   TEXT    (   "OpenService failed - %s\n"),
                            GetLastErrorText    (   g_szErr,    ERROR_BUFSZ)
                        );

            CloseServiceHandle  (   schSCManager);
        }
    else
            wprintf (   TEXT    (   "OpenSCManager failed - %s\n"),
                        GetLastErrorText    (   g_szErr,    ERROR_BUFSZ)
                    );
}



void    StopService    ( LPCTSTR pszName)
{
    SC_HANDLE   schService;
    SC_HANDLE   schSCManager;

    schSCManager    =   OpenSCManager   (   NULL,                   // machine (NULL == local)
                                            NULL,                   // database (NULL == default)
                                            SC_MANAGER_ALL_ACCESS   // access required
                                        );
    if  (   schSCManager)
        {
            schService  =   OpenService (   schSCManager,
                                            pszName,
                                            SERVICE_ALL_ACCESS
                                        );

            if  (   schService)
                {
                    // try to stop the service
                    if  (   ControlService  (   schService,
                                                SERVICE_CONTROL_STOP,
                                                &g_ssStatus
                                            )
                        )
                        {
                            wprintf (   TEXT    (   "Stopping %s."),
                                        pszName
                                    );

                            Sleep   (   1000 );

                            while   (   QueryServiceStatus  (   schService,
                                                                &g_ssStatus
                                                            )
                                    )
                                    {
                                        if  (       SERVICE_STOP_PENDING    
                                                ==  g_ssStatus.dwCurrentState
                                            )
                                            {
                                                wprintf (   TEXT    (   "."));
                                                Sleep( 1000 );
                                            }
                                        else
                                                break;
                                    }

                            if  (   SERVICE_STOPPED ==  g_ssStatus.dwCurrentState)
                                    wprintf (   TEXT    (   "\n%s stopped.\n"),
                                                pszName
                                            );
                            else
                                    wprintf (   TEXT    (   "\n%s failed to stop.\n"),
                                                pszName
                                            );

                        }

                CloseServiceHandle  (   schService);
            }
            else
                wprintf (   TEXT    (   "OpenService failed - %s\n"),
                            GetLastErrorText    (   g_szErr,    ERROR_BUFSZ)
                        );

            CloseServiceHandle  (   schSCManager);
        }
    else
            wprintf (   TEXT    (   "OpenSCManager failed - %s\n"),
                        GetLastErrorText    (   g_szErr,    ERROR_BUFSZ)
                    );
}
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
AxterAuthor Commented:
0
jkrCommented:
BTW, the above is taken from "production" code, you'll find some other useful code at e.g. http://www.microsoft.com/msj/0298/service.aspx ("Manipulate Windows NT Services by Writing a Service Control Program") and/or http://www.codeproject.com/system/AMFSServiceManager.asp ("MFS Service Manger")
0
Cloud Class® Course: Ruby Fundamentals

This course will introduce you to Ruby, as well as teach you about classes, methods, variables, data structures, loops, enumerable methods, and finishing touches.

jkrCommented:
Don't laugh at me, but that was the link I was looking for between my two comments *s*

Oh, and there it finally is, the 1M in Windows Programming... so many thanks back ;o)
0
AxterAuthor Commented:
I shouldn't have close the question so quickly, because there's still one problem I'm having with this code.

I had to change the following code to get it to compile:
 if (!QueryServiceStatusEx(
  schService,             // handle to service
  SC_STATUS_PROCESS_INFO, // info level
  (LPBYTE)&ssStatus,              // address of structure
  sizeof(SERVICE_STATUS_PROCESS), // size of structure
  &dwBytesNeeded ) )              // if buffer too small
 {
  return 0;
 }

I had to add the type casting for ssStatus.

I'm currently compiling this to 32bit windows, so it's currently not a problem, but in the future, I plan to port the code to 64bit windows.

How can I modify the code so that it will safely compile to a 64bit platform.

Here's the error I'm getting with the original code:

[QUOTE]serviceMain.cpp(259): error C2664: 'QueryServiceStatusEx' : cannot convert parameter 3 from 'SERVICE_STATUS_PROCESS' to 'LPBYTE'[/QUOTE]

0
jkrCommented:
Sorry for the delay - is that what you get when compiling with Win64 error checking enabled? Let me dig out the conversion routines...
0
jkrCommented:
Hm, using /Wp64 I don't get any errors with

#include <windows.h>

int main ()
{
SERVICE_STATUS_PROCESS ssStatus;
DWORD dwBytesNeeded;
SC_HANDLE schService = NULL;

//...

 if (!QueryServiceStatusEx(
  schService,             // handle to service
  SC_STATUS_PROCESS_INFO, // info level
  (LPBYTE)&ssStatus,              // address of structure
  sizeof(SERVICE_STATUS_PROCESS), // size of structure
  &dwBytesNeeded ) )              // if buffer too small
 {
  return 0;
 }

return 0;
}
0
AxterAuthor Commented:
>>is that what you get when compiling with Win64 error checking enabled?
Yes
I have the following compile option:
Yes (/Wp64)


>>Hm, using /Wp64 I don't get any errors with

Yes, but you're type casting.
I don't get the error when I type cast.  I get it when I remove the type cast.
I'm worried the type cast is just covering up a potential 64bit problem.
0
jkrCommented:
Well, you have to type cast anyway, without that, even a 32bit app won't compile. The type cast only isn't necessary when you compile that code as .c and not .cpp - /Wp64 isn't really the reason here.
0
AxterAuthor Commented:
>>Well, you have to type cast anyway, without that, even a 32bit app won't compile.

Never mind.  I was having a brain fart! :-)

Sometimes you just can't see the forest for the trees....
0
jkrCommented:
That's an obviously universal proverb - and sometimes *so* true. Noone is immune to that ;o)
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Microsoft Development

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.