zoukankan      html  css  js  c++  java
  • windows服务控制(开启/停止已有服务)

    #include "stdafx.h"
    #include <windows.h>
    #include <tchar.h>
    #include <strsafe.h>
    #include <aclapi.h>
    
    
    #pragma comment(lib, "advapi32.lib")
    
    TCHAR szCommand[10];
    TCHAR szSvcName[80];
    
    SC_HANDLE schSCManager;
    SC_HANDLE schService;
    
    VOID __stdcall DisplayUsage(void);
    
    VOID __stdcall DoStartSvc(void);
    VOID __stdcall DoUpdateSvcDacl(void);
    VOID __stdcall DoStopSvc(void);
    
    BOOL __stdcall StopDependentServices(void);
    
    //
    // Purpose: 
    //   Entry point function. Executes specified command from user.
    //
    // Parameters:
    //   Command-line syntax is: svccontrol [command] [service_name]
    // 
    // Return value:
    //   None
    //
    void _tmain(int argc, TCHAR *argv[])
    {
        printf("
    ");
        if( argc != 3 )
        {
            printf("ERROR: Incorrect number of arguments
    
    ");
            DisplayUsage();
            return;
        }
    
        StringCchCopy(szCommand, 10, argv[1]);
        StringCchCopy(szSvcName, 80, argv[2]);
    
        if (lstrcmpi( szCommand, TEXT("start")) == 0 )
            DoStartSvc();
        else if (lstrcmpi( szCommand, TEXT("dacl")) == 0 )
            DoUpdateSvcDacl();
        else if (lstrcmpi( szCommand, TEXT("stop")) == 0 )
            DoStopSvc();
        else 
        {
            _tprintf(TEXT("Unknown command (%s)
    
    "), szCommand);
            DisplayUsage();
        }
    }
    
    VOID __stdcall DisplayUsage()
    {
        printf("Description:
    ");
        printf("	Command-line tool that controls a service.
    
    ");
        printf("Usage:
    ");
        printf("	svccontrol [command] [service_name]
    
    ");
        printf("	[command]
    ");
        printf("	  start
    ");
        printf("	  dacl
    ");
        printf("	  stop
    ");
    }
    
    //
    // Purpose: 
    //   Starts the service if possible.
    //
    // Parameters:
    //   None
    // 
    // Return value:
    //   None
    //
    VOID __stdcall DoStartSvc()
    {
        SERVICE_STATUS_PROCESS ssStatus; 
        DWORD dwOldCheckPoint; 
        DWORD dwStartTickCount;
        DWORD dwWaitTime;
        DWORD dwBytesNeeded;
    
        // Get a handle to the SCM database. 
     
        schSCManager = OpenSCManager( 
            NULL,                    // local computer
            NULL,                    // servicesActive database 
            SC_MANAGER_ALL_ACCESS);  // full access rights 
     
        if (NULL == schSCManager) 
        {
            printf("OpenSCManager failed (%d)
    ", GetLastError());
            return;
        }
    
        // Get a handle to the service.
    
        schService = OpenService( 
            schSCManager,         // SCM database 
            szSvcName,            // name of service 
            SERVICE_ALL_ACCESS);  // full access 
     
        if (schService == NULL)
        { 
            printf("OpenService failed (%d)
    ", GetLastError()); 
            CloseServiceHandle(schSCManager);
            return;
        }    
    
        // Check the status in case the service is not stopped. 
    
        if (!QueryServiceStatusEx( 
                schService,                     // handle to service 
                SC_STATUS_PROCESS_INFO,         // information level
                (LPBYTE) &ssStatus,             // address of structure
                sizeof(SERVICE_STATUS_PROCESS), // size of structure
                &dwBytesNeeded ) )              // size needed if buffer is too small
        {
            printf("QueryServiceStatusEx failed (%d)
    ", GetLastError());
            CloseServiceHandle(schService); 
            CloseServiceHandle(schSCManager);
            return; 
        }
    
        // Check if the service is already running. It would be possible 
        // to stop the service here, but for simplicity this example just returns. 
    
        if(ssStatus.dwCurrentState != SERVICE_STOPPED && ssStatus.dwCurrentState != SERVICE_STOP_PENDING)
        {
            printf("Cannot start the service because it is already running
    ");
            CloseServiceHandle(schService); 
            CloseServiceHandle(schSCManager);
            return; 
        }
    
        // Save the tick count and initial checkpoint.
    
        dwStartTickCount = GetTickCount();
        dwOldCheckPoint = ssStatus.dwCheckPoint;
    
        // Wait for the service to stop before attempting to start it.
    
        while (ssStatus.dwCurrentState == SERVICE_STOP_PENDING)
        {
            // Do not wait longer than the wait hint. A good interval is 
            // one-tenth of the wait hint but not less than 1 second  
            // and not more than 10 seconds. 
     
            dwWaitTime = ssStatus.dwWaitHint / 10;
    
            if( dwWaitTime < 1000 )
                dwWaitTime = 1000;
            else if ( dwWaitTime > 10000 )
                dwWaitTime = 10000;
    
            Sleep( dwWaitTime );
    
            // Check the status until the service is no longer stop pending. 
     
            if (!QueryServiceStatusEx( 
                    schService,                     // handle to service 
                    SC_STATUS_PROCESS_INFO,         // information level
                    (LPBYTE) &ssStatus,             // address of structure
                    sizeof(SERVICE_STATUS_PROCESS), // size of structure
                    &dwBytesNeeded ) )              // size needed if buffer is too small
            {
                printf("QueryServiceStatusEx failed (%d)
    ", GetLastError());
                CloseServiceHandle(schService); 
                CloseServiceHandle(schSCManager);
                return; 
            }
    
            if ( ssStatus.dwCheckPoint > dwOldCheckPoint )
            {
                // Continue to wait and check.
    
                dwStartTickCount = GetTickCount();
                dwOldCheckPoint = ssStatus.dwCheckPoint;
            }
            else
            {
                if(GetTickCount()-dwStartTickCount > ssStatus.dwWaitHint)
                {
                    printf("Timeout waiting for service to stop
    ");
                    CloseServiceHandle(schService); 
                    CloseServiceHandle(schSCManager);
                    return; 
                }
            }
        }
    
        // Attempt to start the service.
    
        if (!StartService(
                schService,  // handle to service 
                0,           // number of arguments 
                NULL) )      // no arguments 
        {
            printf("StartService failed (%d)
    ", GetLastError());
            CloseServiceHandle(schService); 
            CloseServiceHandle(schSCManager);
            return; 
        }
        else printf("Service start pending...
    "); 
    
        // Check the status until the service is no longer start pending. 
     
        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
        {
            printf("QueryServiceStatusEx failed (%d)
    ", GetLastError());
            CloseServiceHandle(schService); 
            CloseServiceHandle(schSCManager);
            return; 
        }
     
        // Save the tick count and initial checkpoint.
    
        dwStartTickCount = GetTickCount();
        dwOldCheckPoint = ssStatus.dwCheckPoint;
    
        while (ssStatus.dwCurrentState == SERVICE_START_PENDING) 
        { 
            // Do not wait longer than the wait hint. A good interval is 
            // one-tenth the wait hint, but no less than 1 second and no 
            // more than 10 seconds. 
     
            dwWaitTime = ssStatus.dwWaitHint / 10;
    
            if( dwWaitTime < 1000 )
                dwWaitTime = 1000;
            else if ( dwWaitTime > 10000 )
                dwWaitTime = 10000;
    
            Sleep( dwWaitTime );
    
            // Check the status again. 
     
            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
            {
                printf("QueryServiceStatusEx failed (%d)
    ", GetLastError());
                break; 
            }
     
            if ( ssStatus.dwCheckPoint > dwOldCheckPoint )
            {
                // Continue to wait and check.
    
                dwStartTickCount = GetTickCount();
                dwOldCheckPoint = ssStatus.dwCheckPoint;
            }
            else
            {
                if(GetTickCount()-dwStartTickCount > ssStatus.dwWaitHint)
                {
                    // No progress made within the wait hint.
                    break;
                }
            }
        } 
    
        // Determine whether the service is running.
    
        if (ssStatus.dwCurrentState == SERVICE_RUNNING) 
        {
            printf("Service started successfully.
    "); 
        }
        else 
        { 
            printf("Service not started. 
    ");
            printf("  Current State: %d
    ", ssStatus.dwCurrentState); 
            printf("  Exit Code: %d
    ", ssStatus.dwWin32ExitCode); 
            printf("  Check Point: %d
    ", ssStatus.dwCheckPoint); 
            printf("  Wait Hint: %d
    ", ssStatus.dwWaitHint); 
        } 
    
        CloseServiceHandle(schService); 
        CloseServiceHandle(schSCManager);
    }
    
    //
    // Purpose: 
    //   Updates the service DACL to grant start, stop, delete, and read
    //   control access to the Guest account.
    //
    // Parameters:
    //   None
    // 
    // Return value:
    //   None
    //
    VOID __stdcall DoUpdateSvcDacl()
    {
        EXPLICIT_ACCESS      ea;
        SECURITY_DESCRIPTOR  sd;
        PSECURITY_DESCRIPTOR psd            = NULL;
        PACL                 pacl           = NULL;
        PACL                 pNewAcl        = NULL;
        BOOL                 bDaclPresent   = FALSE;
        BOOL                 bDaclDefaulted = FALSE;
        DWORD                dwError        = 0;
        DWORD                dwSize         = 0;
        DWORD                dwBytesNeeded  = 0;
    
        // Get a handle to the SCM database. 
     
        schSCManager = OpenSCManager( 
            NULL,                    // local computer
            NULL,                    // ServicesActive database 
            SC_MANAGER_ALL_ACCESS);  // full access rights 
     
        if (NULL == schSCManager) 
        {
            printf("OpenSCManager failed (%d)
    ", GetLastError());
            return;
        }
    
        // Get a handle to the service
    
        schService = OpenService( 
            schSCManager,              // SCManager database 
            szSvcName,                 // name of service 
            READ_CONTROL | WRITE_DAC); // access
     
        if (schService == NULL)
        { 
            printf("OpenService failed (%d)
    ", GetLastError()); 
            CloseServiceHandle(schSCManager);
            return;
        }    
    
        // Get the current security descriptor.
    
        if (!QueryServiceObjectSecurity(schService,
            DACL_SECURITY_INFORMATION, 
            &psd,           // using NULL does not work on all versions
            0, 
            &dwBytesNeeded))
        {
            if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
            {
                dwSize = dwBytesNeeded;
                psd = (PSECURITY_DESCRIPTOR)HeapAlloc(GetProcessHeap(),
                        HEAP_ZERO_MEMORY, dwSize);
                if (psd == NULL)
                {
                    // Note: HeapAlloc does not support GetLastError.
                    printf("HeapAlloc failed
    ");
                    goto dacl_cleanup;
                }
      
                if (!QueryServiceObjectSecurity(schService,
                    DACL_SECURITY_INFORMATION, psd, dwSize, &dwBytesNeeded))
                {
                    printf("QueryServiceObjectSecurity failed (%d)
    ", GetLastError());
                    goto dacl_cleanup;
                }
            }
            else 
            {
                printf("QueryServiceObjectSecurity failed (%d)
    ", GetLastError());
                goto dacl_cleanup;
            }
        }
    
        // Get the DACL.
    
        if (!GetSecurityDescriptorDacl(psd, &bDaclPresent, &pacl,
                                       &bDaclDefaulted))
        {
            printf("GetSecurityDescriptorDacl failed(%d)
    ", GetLastError());
            goto dacl_cleanup;
        }
    
        // Build the ACE.
    
        BuildExplicitAccessWithName(&ea, TEXT("GUEST"),
            SERVICE_START | SERVICE_STOP | READ_CONTROL | DELETE,
            SET_ACCESS, NO_INHERITANCE);
    
        dwError = SetEntriesInAcl(1, &ea, pacl, &pNewAcl);
        if (dwError != ERROR_SUCCESS)
        {
            printf("SetEntriesInAcl failed(%d)
    ", dwError);
            goto dacl_cleanup;
        }
    
        // Initialize a new security descriptor.
    
        if (!InitializeSecurityDescriptor(&sd, 
            SECURITY_DESCRIPTOR_REVISION))
        {
            printf("InitializeSecurityDescriptor failed(%d)
    ", GetLastError());
            goto dacl_cleanup;
        }
    
        // Set the new DACL in the security descriptor.
    
        if (!SetSecurityDescriptorDacl(&sd, TRUE, pNewAcl, FALSE))
        {
            printf("SetSecurityDescriptorDacl failed(%d)
    ", GetLastError());
            goto dacl_cleanup;
        }
    
        // Set the new DACL for the service object.
    
        if (!SetServiceObjectSecurity(schService, 
            DACL_SECURITY_INFORMATION, &sd))
        {
            printf("SetServiceObjectSecurity failed(%d)
    ", GetLastError());
            goto dacl_cleanup;
        }
        else printf("Service DACL updated successfully
    ");
    
    dacl_cleanup:
        CloseServiceHandle(schSCManager);
        CloseServiceHandle(schService);
    
        if(NULL != pNewAcl)
            LocalFree((HLOCAL)pNewAcl);
        if(NULL != psd)
            HeapFree(GetProcessHeap(), 0, (LPVOID)psd);
    }
    
    //
    // Purpose: 
    //   Stops the service.
    //
    // Parameters:
    //   None
    // 
    // Return value:
    //   None
    //
    VOID __stdcall DoStopSvc()
    {
        SERVICE_STATUS_PROCESS ssp;
        DWORD dwStartTime = GetTickCount();
        DWORD dwBytesNeeded;
        DWORD dwTimeout = 30000; // 30-second time-out
        DWORD dwWaitTime;
    
        // Get a handle to the SCM database. 
     
        schSCManager = OpenSCManager( 
            NULL,                    // local computer
            NULL,                    // ServicesActive database 
            SC_MANAGER_ALL_ACCESS);  // full access rights 
     
        if (NULL == schSCManager) 
        {
            printf("OpenSCManager failed (%d)
    ", GetLastError());
            return;
        }
    
        // Get a handle to the service.
    
        schService = OpenService( 
            schSCManager,         // SCM database 
            szSvcName,            // name of service 
            SERVICE_STOP | 
            SERVICE_QUERY_STATUS | 
            SERVICE_ENUMERATE_DEPENDENTS);  
     
        if (schService == NULL)
        { 
            printf("OpenService failed (%d)
    ", GetLastError()); 
            CloseServiceHandle(schSCManager);
            return;
        }    
    
        // Make sure the service is not already stopped.
    
        if ( !QueryServiceStatusEx( 
                schService, 
                SC_STATUS_PROCESS_INFO,
                (LPBYTE)&ssp, 
                sizeof(SERVICE_STATUS_PROCESS),
                &dwBytesNeeded ) )
        {
            printf("QueryServiceStatusEx failed (%d)
    ", GetLastError()); 
            goto stop_cleanup;
        }
    
        if ( ssp.dwCurrentState == SERVICE_STOPPED )
        {
            printf("Service is already stopped.
    ");
            goto stop_cleanup;
        }
    
        // If a stop is pending, wait for it.
    
        while ( ssp.dwCurrentState == SERVICE_STOP_PENDING ) 
        {
            printf("Service stop pending...
    ");
    
            // Do not wait longer than the wait hint. A good interval is 
            // one-tenth of the wait hint but not less than 1 second  
            // and not more than 10 seconds. 
     
            dwWaitTime = ssp.dwWaitHint / 10;
    
            if( dwWaitTime < 1000 )
                dwWaitTime = 1000;
            else if ( dwWaitTime > 10000 )
                dwWaitTime = 10000;
    
            Sleep( dwWaitTime );
    
            if ( !QueryServiceStatusEx( 
                     schService, 
                     SC_STATUS_PROCESS_INFO,
                     (LPBYTE)&ssp, 
                     sizeof(SERVICE_STATUS_PROCESS),
                     &dwBytesNeeded ) )
            {
                printf("QueryServiceStatusEx failed (%d)
    ", GetLastError()); 
                goto stop_cleanup;
            }
    
            if ( ssp.dwCurrentState == SERVICE_STOPPED )
            {
                printf("Service stopped successfully.
    ");
                goto stop_cleanup;
            }
    
            if ( GetTickCount() - dwStartTime > dwTimeout )
            {
                printf("Service stop timed out.
    ");
                goto stop_cleanup;
            }
        }
    
        // If the service is running, dependencies must be stopped first.
    
        StopDependentServices();
    
        // Send a stop code to the service.
    
        if ( !ControlService( 
                schService, 
                SERVICE_CONTROL_STOP, 
                (LPSERVICE_STATUS) &ssp ) )
        {
            printf( "ControlService failed (%d)
    ", GetLastError() );
            goto stop_cleanup;
        }
    
        // Wait for the service to stop.
    
        while ( ssp.dwCurrentState != SERVICE_STOPPED ) 
        {
            Sleep( ssp.dwWaitHint );
            if ( !QueryServiceStatusEx( 
                    schService, 
                    SC_STATUS_PROCESS_INFO,
                    (LPBYTE)&ssp, 
                    sizeof(SERVICE_STATUS_PROCESS),
                    &dwBytesNeeded ) )
            {
                printf( "QueryServiceStatusEx failed (%d)
    ", GetLastError() );
                goto stop_cleanup;
            }
    
            if ( ssp.dwCurrentState == SERVICE_STOPPED )
                break;
    
            if ( GetTickCount() - dwStartTime > dwTimeout )
            {
                printf( "Wait timed out
    " );
                goto stop_cleanup;
            }
        }
        printf("Service stopped successfully
    ");
    
    stop_cleanup:
        CloseServiceHandle(schService); 
        CloseServiceHandle(schSCManager);
    }
    
    BOOL __stdcall StopDependentServices()
    {
        DWORD i;
        DWORD dwBytesNeeded;
        DWORD dwCount;
    
        LPENUM_SERVICE_STATUS   lpDependencies = NULL;
        ENUM_SERVICE_STATUS     ess;
        SC_HANDLE               hDepService;
        SERVICE_STATUS_PROCESS  ssp;
    
        DWORD dwStartTime = GetTickCount();
        DWORD dwTimeout = 30000; // 30-second time-out
    
        // Pass a zero-length buffer to get the required buffer size.
        if ( EnumDependentServices( schService, SERVICE_ACTIVE, 
             lpDependencies, 0, &dwBytesNeeded, &dwCount ) ) 
        {
             // If the Enum call succeeds, then there are no dependent
             // services, so do nothing.
             return TRUE;
        } 
        else 
        {
            if ( GetLastError() != ERROR_MORE_DATA )
                return FALSE; // Unexpected error
    
            // Allocate a buffer for the dependencies.
            lpDependencies = (LPENUM_SERVICE_STATUS) HeapAlloc( 
                GetProcessHeap(), HEAP_ZERO_MEMORY, dwBytesNeeded );
      
            if ( !lpDependencies )
                return FALSE;
    
            __try {
                // Enumerate the dependencies.
                if ( !EnumDependentServices( schService, SERVICE_ACTIVE, 
                    lpDependencies, dwBytesNeeded, &dwBytesNeeded,
                    &dwCount ) )
                return FALSE;
    
                for ( i = 0; i < dwCount; i++ ) 
                {
                    ess = *(lpDependencies + i);
                    // Open the service.
                    hDepService = OpenService( schSCManager, 
                       ess.lpServiceName, 
                       SERVICE_STOP | SERVICE_QUERY_STATUS );
    
                    if ( !hDepService )
                       return FALSE;
    
                    __try {
                        // Send a stop code.
                        if ( !ControlService( hDepService, 
                                SERVICE_CONTROL_STOP,
                                (LPSERVICE_STATUS) &ssp ) )
                        return FALSE;
    
                        // Wait for the service to stop.
                        while ( ssp.dwCurrentState != SERVICE_STOPPED ) 
                        {
                            Sleep( ssp.dwWaitHint );
                            if ( !QueryServiceStatusEx( 
                                    hDepService, 
                                    SC_STATUS_PROCESS_INFO,
                                    (LPBYTE)&ssp, 
                                    sizeof(SERVICE_STATUS_PROCESS),
                                    &dwBytesNeeded ) )
                            return FALSE;
    
                            if ( ssp.dwCurrentState == SERVICE_STOPPED )
                                break;
    
                            if ( GetTickCount() - dwStartTime > dwTimeout )
                                return FALSE;
                        }
                    } 
                    __finally 
                    {
                        // Always release the service handle.
                        CloseServiceHandle( hDepService );
                    }
                }
            } 
            __finally 
            {
                // Always free the enumeration buffer.
                HeapFree( GetProcessHeap(), 0, lpDependencies );
            }
        } 
        return TRUE;
    }

    这是MSDN上的例子,以管理员身份运行控制台。

  • 相关阅读:
    .net core 项目发布IIS
    .net core 项目连接SQL SERVER数据库报错provider: Named Pipes Provider, error: 40 – Could not open a connection to SQL Server) (Microsoft SQL Server, Error
    网络通讯五层架构入门
    TCP协议学习笔记
    路由器和交换机入门随笔
    互联网通讯的过程
    无论做什么行业,都要有自己的积累!
    C#使用sqlserver2005自动创建数据表和自动添加某个字段索引
    c# treeview在指定名称下添加节点
    测试的行业选择
  • 原文地址:https://www.cnblogs.com/duyy/p/3747612.html
Copyright © 2011-2022 走看看