?
Solved

Create and Start a winNT/2000 service

Posted on 2003-03-15
9
Medium Priority
?
202 Views
Last Modified: 2010-08-05
hello !

I'm learning C and C++.
I need to start the following program as a NT/2000 service (all win platforms would be good, but it's not important).
The user will write, for example: service.exe notepad blablah.txt
I'd like the program set itself as a service with the arguments the user entered the first time. If the user execute again the program with some others arguments, should it change the existing service value for the new one ?
I'll be also very glad if there were an option for uninstalling this service, but i don't want to ask you too much ;-)

//service.c
#include <windows.h>
void main(int argc,char *argv[])
    {
    char exec[255];
    sprintf(exec, "%s %s", argv[1], argv[2]);
    WinExec(exec, SW_SHOWNORMAL);
    }

Hoping you understood me,
Thank you to ones that will help me !!
..and sorry for my very bad english :(
0
Comment
Question by:kakou
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
9 Comments
 
LVL 6

Assisted Solution

by:gj62
gj62 earned 450 total points
ID: 8143413
Why are you trying to do this?  It makes very little sense to have a service with a command line interface that simply execs another program.

Here's a good introduction on services, complete with sample code - and WHY you should want to write one...

http://www.commsoft.com/services.html

0
 
LVL 6

Expert Comment

by:gj62
ID: 8143421
Here's another with a bit more detail...

http://www.mailbag.com/users/pengel/
0
 

Author Comment

by:kakou
ID: 8143460
thanks, i'm going to watch your link..

i want to write a service with the program i wrote because it uses arguments and i want, in one question, to learn arguments usage with service creation.
0
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 6

Expert Comment

by:gj62
ID: 8143822
Ahh, if it is a learning exercise, then the information in the above links should help you.

However, arguement usage (how you retrieve and read arguements) is no different in a service than in an actual application...
0
 

Author Comment

by:kakou
ID: 8144894
yeah but i'm french,
i have search for many websites in french but nothing interesting :(
so, because C is a language (like french and english), i'd like someone speak in C ;-)

my english isn't so good, i don't understand your sites at all, really need an application source that use these features to understand it !
0
 
LVL 5

Accepted Solution

by:
Kocil earned 450 total points
ID: 8145322
I though everybody in Europa can speak English, until I was having vacation at Brussel and Amsterdam. I was asking somebody at the train and his only English was, "I ..... not .... know English".

Hei ... this is the one with our familiar langguage.

// File: exec.cpp

#include <windows.h>
#include <tchar.h>

TCHAR* serviceName = TEXT("Exec Service");
SERVICE_STATUS serviceStatus;
SERVICE_STATUS_HANDLE serviceStatusHandle = 0;
HANDLE stopServiceEvent = 0;

void WINAPI ServiceControlHandler( DWORD controlCode )
{
      switch ( controlCode )
      {
            case SERVICE_CONTROL_INTERROGATE:
                  break;

            case SERVICE_CONTROL_SHUTDOWN:
            case SERVICE_CONTROL_STOP:
                  serviceStatus.dwCurrentState = SERVICE_STOP_PENDING;
                  SetServiceStatus( serviceStatusHandle, &serviceStatus );

                  SetEvent( stopServiceEvent );
                  return;

            case SERVICE_CONTROL_PAUSE:
                  break;

            case SERVICE_CONTROL_CONTINUE:
                  break;

            default:
                  if ( controlCode >= 128 && controlCode <= 255 )
                        // user defined control code
                        break;
                  else
                        // unrecognised control code
                        break;
      }

      SetServiceStatus( serviceStatusHandle, &serviceStatus );
}

void WINAPI ServiceMain( DWORD argc, TCHAR* argv[] )
{
      // initialise service status
      serviceStatus.dwServiceType = SERVICE_WIN32;
      serviceStatus.dwCurrentState = SERVICE_STOPPED;
      serviceStatus.dwControlsAccepted = 0;
      serviceStatus.dwWin32ExitCode = NO_ERROR;
      serviceStatus.dwServiceSpecificExitCode = NO_ERROR;
      serviceStatus.dwCheckPoint = 0;
      serviceStatus.dwWaitHint = 0;

      serviceStatusHandle = RegisterServiceCtrlHandler( serviceName, ServiceControlHandler );

      if ( serviceStatusHandle )
      {
            // service is starting
            serviceStatus.dwCurrentState = SERVICE_START_PENDING;
            SetServiceStatus( serviceStatusHandle, &serviceStatus );

            // do initialisation here
            stopServiceEvent = CreateEvent( 0, FALSE, FALSE, 0 );

            // running
            serviceStatus.dwControlsAccepted |= (SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN);
            serviceStatus.dwCurrentState = SERVICE_RUNNING;
            SetServiceStatus( serviceStatusHandle, &serviceStatus );

            // Your action
                // BUT I'M NOT SURE IF EXEC WILL WORK !!!
            char exec[256];
                sprintf(exec, "%s %s", argv[1], argv[2]);
                WinExec(exec, SW_SHOWNORMAL);


            while ( WaitForSingleObject( stopServiceEvent, 5000 ) == WAIT_TIMEOUT );

            // service was stopped
            serviceStatus.dwCurrentState = SERVICE_STOP_PENDING;
            SetServiceStatus( serviceStatusHandle, &serviceStatus );

            // do cleanup here
            CloseHandle( stopServiceEvent );
            stopServiceEvent = 0;

            // service is now stopped
            serviceStatus.dwControlsAccepted &= ~(SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN);
            serviceStatus.dwCurrentState = SERVICE_STOPPED;
            SetServiceStatus( serviceStatusHandle, &serviceStatus );
      }
}

void RunService()
{
      SERVICE_TABLE_ENTRY serviceTable[] =
      {
            { serviceName, ServiceMain },
            { 0, 0 }
      };

      StartServiceCtrlDispatcher( serviceTable );
}

void InstallService()
{
      SC_HANDLE serviceControlManager = OpenSCManager( 0, 0, SC_MANAGER_CREATE_SERVICE );

      if ( serviceControlManager )
      {
            char path[ _MAX_PATH + 1 ];
            if ( GetModuleFileName( 0, path, sizeof(path)/sizeof(path[0]) ) > 0 )
            {
                  SC_HANDLE service = CreateService( serviceControlManager,
                                          serviceName, serviceName,
                                          SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS,
                                          SERVICE_AUTO_START, SERVICE_ERROR_IGNORE, path,
                                          0, 0, 0, 0, 0 );
                  if ( service )
                        CloseServiceHandle( service );
            }

            CloseServiceHandle( serviceControlManager );
      }
}

void UninstallService()
{
      SC_HANDLE serviceControlManager = OpenSCManager( 0, 0, SC_MANAGER_CONNECT );

      if ( serviceControlManager )
      {
            SC_HANDLE service = OpenService( serviceControlManager,
                  serviceName, SERVICE_QUERY_STATUS | DELETE );
            if ( service )
            {
                  SERVICE_STATUS serviceStatus;
                  if ( QueryServiceStatus( service, &serviceStatus ) )
                  {
                        if ( serviceStatus.dwCurrentState == SERVICE_STOPPED )
                              DeleteService( service );
                  }

                  CloseServiceHandle( service );
            }

            CloseServiceHandle( serviceControlManager );
      }
}

int _tmain( int argc, TCHAR* argv[] )
{
      if ( argc > 1 && lstrcmpi( argv[1], TEXT("install") ) == 0 )
      {
            InstallService();
      }
      else if ( argc > 1 && lstrcmpi( argv[1], TEXT("uninstall") ) == 0 )
      {
            UninstallService();
      }
      else
      {
            RunService();
      }

      return 0;
}


0
 

Author Comment

by:kakou
ID: 8150436
hello Kocil,

thank you for your code, but it doesn't seem to accept arguments when installing the service (maybe i'm wrong and i didn't understand it)

i have replace my code because it was written for C and not C++ ;)

here is my new code:

#include <string>
[...]
          // Your action
               // BUT I'M NOT SURE IF EXEC WILL WORK !!!
          string exec = string(argv[1]) + string(" ") + string(argv[2]);
          WinExec(exec.c_str(), SW_SHOWNORMAL);


...and i like the two options: "install" and "uninstall" :)
0
 
LVL 20

Expert Comment

by:jmcg
ID: 10133974
Nothing has happened on this question in more than 9 months. It's time for cleanup!

My recommendation, which I will post in the Cleanup topic area, is to
split points [grade B] between gj62 and Kocil (asker still had unanswered questions).

PLEASE DO NOT ACCEPT THIS COMMENT AS AN ANSWER!

jmcg
EE Cleanup Volunteer
0
 

Author Comment

by:kakou
ID: 10138412
ok that's fine :)
thanks to them :)
0

Featured Post

Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Summary: This tutorial covers some basics of pointer, pointer arithmetic and function pointer. What is a pointer: A pointer is a variable which holds an address. This address might be address of another variable/address of devices/address of fu…
This is a short and sweet, but (hopefully) to the point article. There seems to be some fundamental misunderstanding about the function prototype for the "main" function in C and C++, more specifically what type this function should return. I see so…
The goal of this video is to provide viewers with basic examples to understand and use structures in the C programming language.
The goal of this video is to provide viewers with basic examples to understand how to create, access, and change arrays in the C programming language.
Suggested Courses

764 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question