Solved

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

Posted on 2004-04-04
7
489 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
  • 3
  • 2
  • 2
7 Comments
 
LVL 44

Expert Comment

by:Karl Heinz Kremer
Comment Utility
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
Comment Utility
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
Comment Utility
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
How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

 
LVL 4

Author Comment

by:xassets
Comment Utility
jkr, thats it.

I knew you'd know. big thanks

0
 
LVL 4

Author Comment

by:xassets
Comment Utility
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
Comment Utility
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
Comment Utility
Excellent

thanks once again
0

Featured Post

Free Trending Threat Insights Every Day

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

Join & Write a Comment

Suggested Solutions

Title # Comments Views Activity
MFC Model Dialogs 10 57
Lambda for random numbers problem 7 99
FMX StringGrid1->Canvas->FillRect Problem 3 98
C++ question 3 44
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…
Basic understanding on "OO- Object Orientation" is needed for designing a logical solution to solve a problem. Basic OOAD is a prerequisite for a coder to ensure that they follow the basic design of OO. This would help developers to understand the b…
The goal of the video will be to teach the user the difference and consequence of passing data by value vs passing data by reference in C++. An example of passing data by value as well as an example of passing data by reference will be be given. Bot…
The viewer will learn how to use the return statement in functions in C++. The video will also teach the user how to pass data to a function and have the function return data back for further processing.

728 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

Need Help in Real-Time?

Connect with top rated Experts

9 Experts available now in Live!

Get 1:1 Help Now