Solved

Programmatically Tell if the Apache Web Service is Running and then Stop It

Posted on 2004-04-04
7
505 Views
Last Modified: 2008-02-07
Hi can I tell through API calls if the apache service is running.

Its the usual scenario where users install oracle with all default options and IIS stops working because apache takes over port 80.

So in the installation program I want to detect if the apache service is started and give the user the option of stopping it. If I could call up the service form to change it to manual and stop it that would be OK, or if I can do it from my own form thats OK too.

thanks
0
Comment
Question by:xassets
[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
  • 3
  • 2
  • 2
7 Comments
 
LVL 44

Expert Comment

by:Karl Heinz Kremer
ID: 10751596
You can use the "NET START service" and "NET STOP service" commands to control a service. The command "NET START" prints all currently running services.
0
 
LVL 44

Expert Comment

by:Karl Heinz Kremer
ID: 10751604
Just found this old question that may provide more information http://www.experts-exchange.com/Web/Web_Servers/IIS/Q_20931314.html
0
 
LVL 86

Accepted Solution

by:
jkr earned 500 total points
ID: 10752585
Check out http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dllproc/base/starting_a_service.asp ("Starting a Service") and http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dllproc/base/starting_a_service.asp ("Stopping a Service") which illustrates the basics about how to control services programmatically:

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

// This function attempts to stop a service. It allows the caller to
// specify whether dependent services should also be stopped. It also
// accepts a timeout value, to prevent a scenario in which a service
// shutdown hangs, then the application stopping the service hangs.
//
// Parameters:  
//   hSCM - Handle to the service control manager.
//   hService - Handle to the service to be stopped.
//   fStopDependencies - Indicates whether to stop dependent services.
//   dwTimeout - maximum time (in milliseconds) to wait
//
// If the operation is successful, returns ERROR_SUCCESS. Otherwise,
// returns a system error code.

DWORD StopService( SC_HANDLE hSCM, SC_HANDLE hService,
      BOOL fStopDependencies, DWORD dwTimeout )
{
   SERVICE_STATUS ss;
   DWORD dwStartTime = GetTickCount();

   // Make sure the service is not already stopped
   if ( !QueryServiceStatus( hService, &ss ) )
      return GetLastError();

   if ( ss.dwCurrentState == SERVICE_STOPPED )
      return ERROR_SUCCESS;

   // If a stop is pending, just wait for it
   while ( ss.dwCurrentState == SERVICE_STOP_PENDING )
   {
      Sleep( ss.dwWaitHint );
      if ( !QueryServiceStatus( hService, &ss ) )
         return GetLastError();

      if ( ss.dwCurrentState == SERVICE_STOPPED )
         return ERROR_SUCCESS;

      if ( GetTickCount() - dwStartTime > dwTimeout )
         return ERROR_TIMEOUT;
   }

   // If the service is running, dependencies must be stopped first
   if ( fStopDependencies )
   {
      DWORD i;
      DWORD dwBytesNeeded;
      DWORD dwCount;

      LPENUM_SERVICE_STATUS   lpDependencies = NULL;
      ENUM_SERVICE_STATUS     ess;
      SC_HANDLE               hDepService;

      // Pass a zero-length buffer to get the required buffer size
      if ( EnumDependentServices( hService, SERVICE_ACTIVE,
         lpDependencies, 0, &dwBytesNeeded, &dwCount ) )
      {
         // If the Enum call succeeds, then there are no dependent
         // services so do nothing
      }
      else
      {
         if ( GetLastError() != ERROR_MORE_DATA )
            return GetLastError(); // Unexpected error

         // Allocate a buffer for the dependencies
         lpDependencies = (LPENUM_SERVICE_STATUS) HeapAlloc(
               GetProcessHeap(), HEAP_ZERO_MEMORY, dwBytesNeeded );

         if ( !lpDependencies )
            return GetLastError();

         __try {
            // Enumerate the dependencies
            if ( !EnumDependentServices( hService, SERVICE_ACTIVE,
                  lpDependencies, dwBytesNeeded, &dwBytesNeeded,
                  &dwCount ) )
               return GetLastError();

            for ( i = 0; i < dwCount; i++ )
            {
               ess = *(lpDependencies + i);

               // Open the service
               hDepService = OpenService( hSCM, ess.lpServiceName,
                     SERVICE_STOP | SERVICE_QUERY_STATUS );
               if ( !hDepService )
                  return GetLastError();

               __try {
                   // Send a stop code
                  if ( !ControlService( hDepService,
                           SERVICE_CONTROL_STOP,
                           &ss ) )
                     return GetLastError();

                  // Wait for the service to stop
                  while ( ss.dwCurrentState != SERVICE_STOPPED )
                  {
                      Sleep( ss.dwWaitHint );
                     if ( !QueryServiceStatus( hDepService, &ss ) )
                        return GetLastError();

                     if ( ss.dwCurrentState == SERVICE_STOPPED )
                        break;

                     if ( GetTickCount() - dwStartTime > dwTimeout )
                        return ERROR_TIMEOUT;
                  }

               }
               __finally
               {
                  // Always release the service handle
                  CloseServiceHandle( hDepService );

               }
            }

         }
         __finally
         {
            // Always free the enumeration buffer
            HeapFree( GetProcessHeap(), 0, lpDependencies );
         }
      }
   }

   // Send a stop code to the main service
   if ( !ControlService( hService, SERVICE_CONTROL_STOP, &ss ) )
      return GetLastError();

   // Wait for the service to stop
   while ( ss.dwCurrentState != SERVICE_STOPPED )
   {
      Sleep( ss.dwWaitHint );
      if ( !QueryServiceStatus( hService, &ss ) )
         return GetLastError();

      if ( ss.dwCurrentState == SERVICE_STOPPED )
         break;

      if ( GetTickCount() - dwStartTime > dwTimeout )
         return ERROR_TIMEOUT;
   }

   // Return success
   return ERROR_SUCCESS;
}

To detect whether the service in question is running, the following part is relevant:

   // Make sure the service is not already stopped
   if ( !QueryServiceStatus( hService, &ss ) )
      return GetLastError();

To obtain a service handle, you first need to open the SCM database: http://msdn.microsoft.com/library/en-us/dllproc/base/opening_an_scmanager_database.asp

Then, you need to use 'OpenService()' with the database handle you obtained above:

    // Open a handle to the service.
 
    schService = OpenService(
        schSCManager,           // SCManager database
        "Sample_Srv",           // name of service
        SERVICE_ALL_ACCESS// need to adjust access to the appropriate means
0
[Live Webinar] The Cloud Skills Gap

As Cloud technologies come of age, business leaders grapple with the impact it has on their team's skills and the gap associated with the use of a cloud platform.

Join experts from 451 Research and Concerto Cloud Services on July 27th where we will examine fact and fiction.

 
LVL 4

Author Comment

by:xassets
ID: 10752790
jkr, thats it.

I knew you'd know. big thanks

0
 
LVL 4

Author Comment

by:xassets
ID: 10752870
One more question if you can jkr

How can I change the service start up from "Automatic" to "Manual" programmatically

(so it doesn't come back at the next reboot)
0
 
LVL 86

Expert Comment

by:jkr
ID: 10753201
You can do that using 'QueryServiceConfig()' and 'ChangeServiceConfig()' - see also http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dllproc/base/changing_a_service_configuration.asp ("Changing a Service Configuration"), the code sample on that page pretty much does what you want:

VOID ReconfigureSampleService(BOOL fDisable, LPSTR lpDesc)
{
    SC_LOCK sclLock;
    LPQUERY_SERVICE_LOCK_STATUS lpqslsBuf;
    SERVICE_DESCRIPTION sdBuf;
    DWORD dwBytesNeeded, dwStartType;
 
    // Need to acquire database lock before reconfiguring.
 
    sclLock = LockServiceDatabase(schSCManager);
 
    // If the database cannot be locked, report the details.
 
    if (sclLock == NULL)
    {
        // Exit if the database is not locked by another process.
 
        if (GetLastError() != ERROR_SERVICE_DATABASE_LOCKED)
            MyErrorExit("LockServiceDatabase");
 
        // Allocate a buffer to get details about the lock.
 
        lpqslsBuf = (LPQUERY_SERVICE_LOCK_STATUS) LocalAlloc(
            LPTR, sizeof(QUERY_SERVICE_LOCK_STATUS)+256);
        if (lpqslsBuf == NULL)
            MyErrorExit("LocalAlloc");
 
        // Get and print the lock status information.
 
        if (!QueryServiceLockStatus(
            schSCManager,
            lpqslsBuf,
            sizeof(QUERY_SERVICE_LOCK_STATUS)+256,
            &dwBytesNeeded) )
            MyErrorExit("QueryServiceLockStatus");
 
        if (lpqslsBuf->fIsLocked)
            printf("Locked by: %s, duration: %d seconds\n",
                lpqslsBuf->lpLockOwner,
                lpqslsBuf->dwLockDuration);
        else
            printf("No longer locked\n");
 
        LocalFree(lpqslsBuf);
        MyErrorExit("Could not lock database");
    }
 
    // The database is locked, so it is safe to make changes.
 
    // Open a handle to the service.
 
    schService = OpenService(
        schSCManager,           // SCManager database
        "Sample_Srv",           // name of service
        SERVICE_CHANGE_CONFIG); // need CHANGE access
    if (schService == NULL)
        MyErrorExit("OpenService");
 
    dwStartType = (fDisable) ? SERVICE_DISABLED :
                            SERVICE_DEMAND_START;
 
    // Make the changes.

    if (! ChangeServiceConfig(
        schService,        // handle of service
        SERVICE_NO_CHANGE, // service type: no change
        dwStartType,       // change service start type
        SERVICE_NO_CHANGE, // error control: no change
        NULL,              // binary path: no change
        NULL,              // load order group: no change
        NULL,              // tag ID: no change
        NULL,              // dependencies: no change
        NULL,              // account name: no change
        NULL,              // password: no change
        NULL) )            // display name: no change
    {
        MyErrorExit("ChangeServiceConfig");
    }
    else
        printf("ChangeServiceConfig SUCCESS\n");
 
    sdBuf.lpDescription = lpDesc;

    if( !ChangeServiceConfig2(
        schService,                 // handle to service
        SERVICE_CONFIG_DESCRIPTION, // change: description
        &sdBuf) )                   // value: new description
    {
        MyErrorExit("ChangeServiceConfig2");
    }
    else
        printf("ChangeServiceConfig2 SUCCESS\n");

    // Release the database lock.
 
    UnlockServiceDatabase(sclLock);
 
    // Close the handle to the service.
 
    CloseServiceHandle(schService);
}
0
 
LVL 4

Author Comment

by:xassets
ID: 10753247
Excellent

thanks once again
0

Featured Post

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!

Question has a verified solution.

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

Errors will happen. It is a fact of life for the programmer. How and when errors are detected have a great impact on quality and cost of a product. It is better to detect errors at compile time, when possible and practical. Errors that make their wa…
Introduction This article is the first in a series of articles about the C/C++ Visual Studio Express debugger.  It provides a quick start guide in using the debugger. Part 2 focuses on additional topics in breakpoints.  Lastly, Part 3 focuses on th…
The viewer will learn how to user default arguments when defining functions. This method of defining functions will be contrasted with the non-default-argument of defining functions.
The viewer will be introduced to the member functions push_back and pop_back of the vector class. The video will teach the difference between the two as well as how to use each one along with its functionality.

617 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