编写Windows系统服务进程(VS2005 C++)

来源:互联网 发布:美容行业大数据分析 编辑:程序博客网 时间:2024/05/16 16:18

Windows服务程序运行于系统的后台来处理一些系统操作,当然我们有时也希望自已能够实现系像系统服务那样对特定的程序

进行操作.至于关于Windows操作系统中系统服务的详细说明,网上资料有很多了,偶也就不多写了,怕写也写不明白.写在这里的

目的也是希望给自已一个记载,省得以后用到的时候找不到了.嘿嘿.

在这里我通过系统服务实现了保证某应用程序一直处于运行状态这样一个简单功能:服务启动后,检测系统中某应用程序(Okilpr.exe,当然也可以换成记事本之类的应用程序,在这里称为App吧)是否处于运行状态,如果App已经处于运行状态,则不对其进行任何操作,如果App已被

用户关闭,那么这个系统服务就会根据App所在的路径,创建一个App进程,则启动它,并将启动成功与否的log信息写入到log文件中.. 这就是服务实现的功能.

那么为了使服务便于操作,创建了一个界面操作小工具,对服务能够进行Install,Start,Stop,Quer,Delete功能,并将服务的运

行状态在界面上进行显示.


作为一个行走在Windows编程道路上的新人,经验非常有限;在程序的编写中,借鉴了 Northtibet译的MSDN"Five Steps to Writing Windows Services in C"(用 C 语言编写 Windows 服务程序的五个步骤http://www.vckbase.com/document/viewdoc/?id=1474)

实现后的界面如下所示:

Dialog of Windows Service Control

因为不知道如何将代码上传,只好贴代码了.

 

//About the System Service

//Date:2009-12-14

//Function:Use the Service to start Application.

//Author:yzli


#include <windows.h>
#include <stdio.h>
#include <string.h>
#include <tlhelp32.h>

#define SLEEP_TIME 5000
#define LOGFILE "C://MyServices//memstatus.txt"

////////////////////////////////////////////////////////////
// Declare several global variables to share
// their values across multiple functions of your program.
////////////////////////////////////////////////////////////

SERVICE_STATUS          ServiceStatus;
SERVICE_STATUS_HANDLE   hStatus;

////////////////////////////////////////////////////////////
// Make the forward definitions of functions prototypes.
//
////////////////////////////////////////////////////////////

void  ServiceMain(int argc, char** argv);
void  ControlHandler(DWORD request);
int InitService();

int WriteToLog(char* str)
{
    //Get Current Directory
    TCHAR szLogPath[MAX_PATH];
   TCHAR szLogName[MAX_PATH];
   ZeroMemory(szLogPath, MAX_PATH);

   GetModuleFileName(NULL,szLogPath,sizeof(szLogPath));
   lstrcpy(szLogName,"MemoryStatus.txt");
  
   int iLen = strlen(szLogPath);
   int iNameLen = strlen(szLogName);
   iLen --;//find from the second-last character.
   while(iLen)
   {
       if(szLogPath[iLen]== '//')
       {
           break;
       }
       iLen--;
   }
   while(iNameLen)
   {
       szLogPath[iLen+ iNameLen] = szLogName[iNameLen-1];
       iNameLen--;
   }

   //Write to Log
   FILE* log;
   log = fopen(szLogPath, "a+");
   if (log == NULL){
       OutputDebugString("Log file open failed.");
      return -1;
   }
   fprintf(log, "%s/n", str);
   fclose(log);
   return 0;
}
///////////////////////////////////////////////////////////////////
BOOL IsOkilprRun()
{
    HANDLE hProcessSnap = NULL;
    BOOL   bRet         = FALSE;
    PROCESSENTRY32 pe32 = {0};
    TCHAR lpName[MAX_PATH];
   
    lstrcpy(lpName,"Okilpr.exe");

    hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
    if(hProcessSnap == INVALID_HANDLE_VALUE)
    {
        return FALSE;
    }

    pe32.dwSize = sizeof(PROCESSENTRY32);

    if(Process32First(hProcessSnap,&pe32))
    {
        do
        {
            if(!strcmp(_strupr(pe32.szExeFile),_strupr(lpName)))
            {
                CloseHandle(hProcessSnap);
                return TRUE;
            }
        }while(Process32Next(hProcessSnap,&pe32));
    }
    else
    {
        CloseHandle(hProcessSnap);
        return FALSE;
    }

}
///////////////////////////////////////////////////////////////////
BOOL GetTokenByName(HANDLE &hToken, LPSTR lpName)
{
    if(!lpName)
    {
        return FALSE;
    }

    HANDLE hProcessSnap = NULL;
    BOOL   bRet         = FALSE;
    PROCESSENTRY32 pe32 = {0};

    hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
    if(hProcessSnap == INVALID_HANDLE_VALUE)
    {
        return FALSE;
    }

    pe32.dwSize = sizeof(PROCESSENTRY32);

    if(Process32First(hProcessSnap,&pe32))
    {
        do
        {
            if(!strcmp(_strupr(pe32.szExeFile),_strupr(lpName)))
            {
                HANDLE hProcess = OpenProcess(
                    PROCESS_QUERY_INFORMATION,
                    FALSE,
                    pe32.th32ProcessID);
                bRet = OpenProcessToken(hProcess,TOKEN_ALL_ACCESS, &hToken);
                CloseHandle(hProcessSnap);
                return (bRet);
            }
        }while(Process32Next(hProcessSnap, &pe32));
        bRet = TRUE;
    }
    else
    {
        bRet =FALSE;
    }

    CloseHandle(hProcessSnap);
    return(bRet);
}
//////////////////////////////////////////////////////////////
BOOL RunProcess(LPCSTR lpImage)
{
    if(!lpImage)
        return FALSE;

    HANDLE hToken;
 
    if(!GetTokenByName(hToken,"WINLOGON.EXE"))
    {
        return FALSE;
    }

    STARTUPINFO si;
    PROCESS_INFORMATION pi;

    ZeroMemory(&si, sizeof(STARTUPINFO));
    si.cb = sizeof(STARTUPINFO);
    si.lpDesktop = TEXT("winsta0//default");

    BOOL bResult = CreateProcessAsUser(hToken,
        lpImage,NULL,NULL,NULL,FALSE,NORMAL_PRIORITY_CLASS,NULL,NULL,&si,&pi);

    CloseHandle(hToken);

    if(bResult)
    {
        WriteToLog("CreateProcessAsUser OK!/r/n");
    }
    else
    {
        WriteToLog("CreateProcessAsUser false!/r/n");
    }
    return bResult;

}
//////////////////////////////////////////////////////////////

// Service initialization

int InitService()
{
    OutputDebugString("Monitoring started.");
    int result;
    result = WriteToLog("Monitoring started.");
    return(result);
}

// Control Handler
void ControlHandler(DWORD request)
{
   switch(request)
   {
      case SERVICE_CONTROL_STOP:
         OutputDebugString("Monitoring stopped.");
         WriteToLog("Monitoring stopped.");

         ServiceStatus.dwWin32ExitCode = 0;
         ServiceStatus.dwCurrentState = SERVICE_STOPPED;
         SetServiceStatus (hStatus, &ServiceStatus);
         return;
 
      case SERVICE_CONTROL_SHUTDOWN:
         OutputDebugString("Monitoring stopped.");
         WriteToLog("Monitoring stopped.");

         ServiceStatus.dwWin32ExitCode = 0;
         ServiceStatus.dwCurrentState = SERVICE_STOPPED;
         SetServiceStatus (hStatus, &ServiceStatus);
         return;
       
      default:
         break;
    }
 
    // Report current status
    SetServiceStatus (hStatus, &ServiceStatus);
 
    return;
}
/////////////////////////////////////////////////////////////////////

/////////////////////////////////////////////////////////////////////


void ServiceMain(int argc, char** argv)
{
   int error;
   //The Okilpr.exe will be started onley one time by service.
   BOOL bManualStart = FALSE;//if LPR was started,the value is TRUE;
 
   ServiceStatus.dwServiceType = SERVICE_WIN32;
   ServiceStatus.dwCurrentState = SERVICE_START_PENDING;
   ServiceStatus.dwControlsAccepted   = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN;
   ServiceStatus.dwWin32ExitCode = 0;
   ServiceStatus.dwServiceSpecificExitCode = 0;
   ServiceStatus.dwCheckPoint = 0;
   ServiceStatus.dwWaitHint = 0;
 
   hStatus = RegisterServiceCtrlHandler(
      "MemoryStatus",
      (LPHANDLER_FUNCTION)ControlHandler);
   if (hStatus == (SERVICE_STATUS_HANDLE)0)
   {
      // Registering Control Handler failed
      return;
   } 

   // Initialize Service
   error = InitService();
   if (error)
   {
      // Initialization failed
      ServiceStatus.dwCurrentState = SERVICE_STOPPED;
      ServiceStatus.dwWin32ExitCode = -1;
      SetServiceStatus(hStatus, &ServiceStatus);
      return;
   }
 
  // We report the running status to SCM.
   ServiceStatus.dwCurrentState = SERVICE_RUNNING;
   SetServiceStatus (hStatus, &ServiceStatus);
 
   MEMORYSTATUS memory;
   // The worker loop of a service
   while (ServiceStatus.dwCurrentState ==
          SERVICE_RUNNING)
   {
      ///*****************************************************************
       char szPath[MAX_PATH], szCommand[MAX_PATH];
        //////SECURITY_ATTRIBUTES sa;
        //////STARTUPINFO si;
        //////PROCESS_INFORMATION pi;

        ZeroMemory(szPath,MAX_PATH);
        ZeroMemory(szCommand,MAX_PATH);
        //////sprintf( szPath,"%s","C://Program Files//Okidata//OKI LPR Utility");
        sprintf( szCommand,"%s","C://Program Files//Okidata//OKI LPR Utility//Okilpr.exe");
        ////////sprintf( szCommand,"%s","Okilpr.exe");

        //////ZeroMemory(&sa, sizeof(SECURITY_ATTRIBUTES));
        //////sa.nLength = sizeof(SECURITY_ATTRIBUTES);
        //////ZeroMemory(&si, sizeof(STARTUPINFO));
        //////si.cb = sizeof(STARTUPINFO);
        //////si.dwFlags = STARTF_USESHOWWINDOW;
        //////si.wShowWindow = SW_SHOWMINIMIZED;
        //////si.lpDesktop = "WinSta0//Default";
        //////ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));
        //////
        //////if(!FindWindow("Okilpr", NULL))
        //////{
        //////    if(CreateProcess(NULL, szCommand, &sa, &sa, TRUE, CREATE_SUSPENDED, NULL, szPath, &si, &pi))
        //////    {
        //////        ResumeThread(pi.hThread);
        //////        WaitForInputIdle(pi.hProcess, 10000);
        //////        while(!FindWindow("Okilpr", NULL));
        //////        CloseHandle(pi.hProcess);
        //////        CloseHandle(pi.hThread);
        //////       
        //////        if(!WriteToLog("LPR process start."))
        //////        {
        //////            OutputDebugString("SUCCESS/n");
        //////        }
        //////    }
        //////}
      //**************************************************************

        if((!IsOkilprRun()) && (!bManualStart))
        {
            RunProcess(szCommand);
            bManualStart = TRUE;
        }
     
      //***************************************************************
       char buffer[16];
      GlobalMemoryStatus(&memory);
      sprintf(buffer, "%d", memory.dwAvailPhys);

      OutputDebugString(buffer);
      int result = WriteToLog(buffer);
      if (result)
      {
         ServiceStatus.dwCurrentState =
            SERVICE_STOPPED;
         ServiceStatus.dwWin32ExitCode      = -1;
         SetServiceStatus(hStatus,
                          &ServiceStatus);
         return;
      }
      Sleep(SLEEP_TIME);
   }
   return;
}

void main(int argc, char* argv[])
{
   SERVICE_TABLE_ENTRY ServiceTable[2];
   ServiceTable[0].lpServiceName = "MemoryStatus";
   ServiceTable[0].lpServiceProc = (LPSERVICE_MAIN_FUNCTION)ServiceMain;

   ServiceTable[1].lpServiceName = NULL;
   ServiceTable[1].lpServiceProc = NULL;
   // Start the control dispatcher thread for our service
   StartServiceCtrlDispatcher(ServiceTable);
}



//About the Control Dialog of Service

//Date:2009-12-14

//Function:Use the Service to start Application.

//Author:yzli


// ServiceCtrlDlg.cpp : implementation file
//


#include "stdafx.h"
#include "ServiceCtrl.h"
#include "ServiceCtrlDlg.h"
#include <windows.h>
#include <winsvc.h>
#include <shlobj.h>
#include <dsclient.h>
       


#ifdef _DEBUG
#define new DEBUG_NEW
#endif


// CServiceCtrlDlg dialog



CServiceCtrlDlg::CServiceCtrlDlg(CWnd* pParent /*=NULL*/)
    : CDialog(CServiceCtrlDlg::IDD, pParent)
{
    m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
    m_uiTimer = 0;
}

void CServiceCtrlDlg::DoDataExchange(CDataExchange* pDX)
{
    CDialog::DoDataExchange(pDX);
}

BEGIN_MESSAGE_MAP(CServiceCtrlDlg, CDialog)
    ON_WM_PAINT()
    ON_WM_QUERYDRAGICON()
 
    //}}AFX_MSG_MAP   
    ON_BN_CLICKED(IDC_BTNSTART, &CServiceCtrlDlg::OnBnClickedBtnstart)
    ON_BN_CLICKED(IDC_BTNSTOP, &CServiceCtrlDlg::OnBnClickedBtnstop)
    ON_BN_CLICKED(IDC_BTNQUERY, &CServiceCtrlDlg::OnBnClickedBtnquery)
    ON_WM_TIMER()
    ON_WM_DESTROY()
    ON_BN_CLICKED(IDC_INSTALL, &CServiceCtrlDlg::OnBnClickedInstall)
    ON_BN_CLICKED(IDC_DELETE, &CServiceCtrlDlg::OnBnClickedDelete)
END_MESSAGE_MAP()


// CServiceCtrlDlg message handlers

BOOL CServiceCtrlDlg::OnInitDialog()
{
    CDialog::OnInitDialog();

    // Set the icon for this dialog.  The framework does this automatically
    //  when the application's main window is not a dialog

    SetIcon(m_hIcon, TRUE);            // Set big icon
    SetIcon(m_hIcon, FALSE);        // Set small icon

    // TODO: Add extra initialization here
   
    // Set the default service name

     SetDlgItemText(IDC_SERVNAME, _T("MemoryStatus"));

    // Start the auto-update timer
    m_uiTimer = SetTimer(1,1000, NULL); // 1 second interval

    //**************************************************************************
   
    //**************************************************************************
   


    return TRUE;  // return TRUE  unless you set the focus to a control
}

// If you add a minimize button to your dialog, you will need the code below
//  to draw the icon.  For MFC applications using the document/view model,
//  this is automatically done for you by the framework.

void CServiceCtrlDlg::OnPaint()
{
    if (IsIconic())
    {
        CPaintDC dc(this); // device context for painting

        SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);

        // Center icon in client rectangle
        int cxIcon = GetSystemMetrics(SM_CXICON);
        int cyIcon = GetSystemMetrics(SM_CYICON);
        CRect rect;
        GetClientRect(&rect);
        int x = (rect.Width() - cxIcon + 1) / 2;
        int y = (rect.Height() - cyIcon + 1) / 2;

        // Draw the icon
        dc.DrawIcon(x, y, m_hIcon);
    }
    else
    {
        CDialog::OnPaint();
    }
}

// The system calls this function to obtain the cursor to display while the user drags
//  the minimized window.

HCURSOR CServiceCtrlDlg::OnQueryDragIcon()
{
    return static_cast<HCURSOR>(m_hIcon);
}


void CServiceCtrlDlg::OnBnClickedBtnstart()
{
    // TODO: Add your control notification handler code here
    // Get the service name

    char szServiceName[64];
    ZeroMemory(szServiceName,64);

    szServiceName[0] = '/0';
    GetDlgItemText(IDC_SERVNAME, (LPTSTR)szServiceName, sizeof(szServiceName));
    if (strlen(szServiceName) == 0) return;
    
    // open the service control manager
    SC_HANDLE hSCM = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
    ASSERT(hSCM);  

    // open the service
    SC_HANDLE hService = OpenService(hSCM,
                                     szServiceName,
                                     SERVICE_ALL_ACCESS);
    ASSERT(hService);

    SERVICE_STATUS ss;
            memset(&ss, 0, sizeof(ss));
            BOOL b = QueryServiceStatus(hService,
                                        &ss);
            if(!b)
            {
                DWORD dwErr = GetLastError();
                ASSERT(0);
            }
            else
            {
                DWORD dwErr = ss.dwWin32ExitCode;
                DWORD dwState = ss.dwCurrentState;

                // If the service is running, send a control request
                // to get its current status

                if (dwState == SERVICE_RUNNING)
                {                
                    AfxMessageBox(_T("The Service is running."));
                    return;
                }
                
            }


    // start the service
    b = StartService(hService, 0, NULL);
    if(!b) {
        DWORD dwErr = GetLastError();
        AfxMessageBox(_T("The Service could not run."));

        return;
    }

    // close the service handle
    CloseServiceHandle(hService);

    // close the service control manager handle
    CloseServiceHandle(hSCM);

    ShowState();
}

void CServiceCtrlDlg::OnBnClickedBtnstop()
{
    // TODO: Add your control notification handler code here
    // Get the service name

    char szServiceName[64];
    szServiceName[0] = '/0';
    GetDlgItemText(IDC_SERVNAME, szServiceName, sizeof(szServiceName));
    if (strlen(szServiceName) == 0) return;
    
    // open the service control manager
    SC_HANDLE hSCM = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
    ASSERT(hSCM);  

    // open the service
    SC_HANDLE hService = OpenService(hSCM,
                                     szServiceName,
                                     SERVICE_ALL_ACCESS);
    ASSERT(hService);

    // stop the service
    SERVICE_STATUS ss;
    BOOL b = ControlService(hService,
                            SERVICE_CONTROL_STOP,
                            &ss);
    if(!b) {
        DWORD dwErr = GetLastError();
        ASSERT(0);
    }

    // close the service handle
    CloseServiceHandle(hService);

    // close the service control manager handle

    CloseServiceHandle(hSCM);

    ShowState();
}

void CServiceCtrlDlg::OnBnClickedBtnquery()
{
    // TODO: Add your control notification handler code here
    ShowState();
}
void CServiceCtrlDlg::ShowState()
{
     // Get the service name
    char szServiceName[64];
    szServiceName[0] = '/0';
    DWORD dwState = 0xFFFFFFFF;
    DWORD dwErr = 0xFFFFFFFF;
    GetDlgItemText(IDC_SERVNAME, szServiceName, sizeof(szServiceName));
    if (strlen(szServiceName) != 0) {
    
        // open the service control manager
        SC_HANDLE hSCM = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
        ASSERT(hSCM);  

        // open the service
        SC_HANDLE hService = OpenService(hSCM,
                                         szServiceName,
                                         SERVICE_ALL_ACCESS);
        if (hService) {

            // Get the current status
            SERVICE_STATUS ss;
            memset(&ss, 0, sizeof(ss));
            BOOL b = QueryServiceStatus(hService,
                                        &ss);
            if(!b) {
                DWORD dwErr = GetLastError();
                ASSERT(0);
            } else {
                dwErr = ss.dwWin32ExitCode;
                dwState = ss.dwCurrentState;

                // If the service is running, send a control request
                // to get its current status

                if (dwState == SERVICE_RUNNING) {
                    b = ::ControlService(hService,
                                         SERVICE_CONTROL_INTERROGATE,
                                         &ss);
                    if (b) {
                        dwErr = ss.dwWin32ExitCode;
                        dwState = ss.dwCurrentState;
                    }
                }
            }

            // close the service handle
            CloseServiceHandle(hService);
        }

        // close the service control manager handle
        CloseServiceHandle(hSCM);
    }

    // See what we got
    char buf[64];
    if (dwErr == 0xFFFFFFFF) {
        SetDlgItemText(IDC_EXITCODE, "<unknown>");
    } else {
        sprintf(buf, "%8.8lXH (%d)", dwErr, dwErr);
        SetDlgItemText(IDC_EXITCODE, buf);
    }

    switch (dwState) {
    case SERVICE_STOPPED:
        strcpy(buf, "Stopped");
        break;
    case SERVICE_START_PENDING:
        strcpy(buf, "Start pending");
        break;
    case SERVICE_STOP_PENDING:
        strcpy(buf, "Stop pending");
        break;
    case SERVICE_RUNNING:
        strcpy(buf, "Running");
        break;
    case SERVICE_CONTINUE_PENDING:
        strcpy(buf, "Continue pending");
        break;
    case SERVICE_PAUSE_PENDING:
        strcpy(buf, "Pause pending");
        break;
    case SERVICE_PAUSED:
        strcpy(buf, "Paused");
        break;
    default:
        strcpy(buf, "<Unknown>");
        break;
    }
    SetDlgItemText(IDC_STATE, buf);

}
void CServiceCtrlDlg::OnTimer(UINT_PTR nIDEvent)
{
    // TODO: Add your message handler code here and/or call default
    ShowState();

    CDialog::OnTimer(nIDEvent);
}

void CServiceCtrlDlg::OnDestroy()
{
    CDialog::OnDestroy();

    // TODO: Add your message handler code here

   
    if (m_uiTimer != 0) {
        KillTimer(1);
    }   

}

void CServiceCtrlDlg::OnBnClickedInstall()
{
    // TODO: Add your control notification handler code here
    SC_HANDLE hSCM, hService;
    char szServiceName[64];
    ZeroMemory(szServiceName,64);
    TCHAR szServicePath[MAX_PATH];
      
    ZeroMemory(szServicePath,MAX_PATH);
    //lstrcpy( szServicePath, _T("C://MyServices//MemoryStatus.exe") );
    GetDlgItemText(IDC_SERVNAME,szServiceName,sizeof(szServiceName));

    GetModuleFileName(NULL,szServicePath,sizeof(szServicePath));
    CString strServicePath, strServiceName;
    strServicePath.Format(_T("%s"),szServicePath);
    strServiceName.Format(_T("%s"),szServiceName); 
    int iPos =strServicePath.ReverseFind('//');
    if(iPos)
    {
        strServicePath = strServicePath.Left(iPos+1);
        strServicePath += strServiceName;
        strServicePath += _T(".exe");
    }

    GetDlgItemText(IDC_SERVNAME,szServiceName,sizeof(szServiceName));
    if(strlen(szServiceName) !=0)
    {
         // open the service control manager
        hSCM = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
        ASSERT(hSCM);  

        // open the service
        SC_HANDLE hService = OpenService(hSCM,
                                         szServiceName,
                                         SERVICE_ALL_ACCESS);
        if(hService)
        {
            ::AfxMessageBox(_T("The Service has installed."));
            return;
        }
       

          hService = CreateService(
            hSCM,//SCManager database
             szServiceName,//name of Service
             szServiceName,//Service name to display
            SERVICE_ALL_ACCESS,//desired access
            SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS,//Service type
            SERVICE_AUTO_START,//start type
            SERVICE_ERROR_NORMAL,//error control type
            (LPCTSTR)strServicePath, //path to service's binary
            NULL,//no load ordering group
            NULL,//no tag identifier
            NULL,//no dependencies
            NULL,//localSystem account
            NULL);//no Password

           
        if(hService)
        {
            AfxMessageBox(_T("Service is installed successfully."));
        }
        else
        {
            AfxMessageBox(_T("Service is installed Failed."));
        }
       
        CloseServiceHandle(hService);
        CloseServiceHandle(hSCM);

    }
}

void CServiceCtrlDlg::OnBnClickedDelete()
{
    // TODO: Add your control notification handler code here
        SC_HANDLE hSCM, hService;
    char szServiceName[64];
    ZeroMemory(szServiceName,64);

    GetDlgItemText(IDC_SERVNAME,szServiceName,sizeof(szServiceName));
    if(strlen(szServiceName) !=0)
    {
        hSCM = OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS);
        ASSERT(hSCM);
        hService = OpenService(hSCM,szServiceName,SERVICE_ALL_ACCESS);
        if(hService)
        {
            if(!DeleteService(hService))
            {
                AfxMessageBox(_T("The Service is delete failed."));
            }
            else
            {
                AfxMessageBox(_T("The Service is delete Successfully."));
            }
        }
        CloseServiceHandle(hService);
        CloseServiceHandle(hSCM);
    }
}
///END

原创粉丝点击