创建Service程序并监控有界面的进程实现

本文提供了一段C++代码,用于创建一个名为'Win8 Server'的服务程序,该服务能够启动、停止并监控有界面的进程。服务安装、卸载、启动和停止等功能通过命令行参数实现。代码中特别注意了在WinLogon桌面下启动进程的细节。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

直接上代码,比较简单,容易看懂。

需要注意的是:启动的监控程序默认桌面是WinLogon,如果登陆成功后,被启动的程序,需要设置活动桌面。(通过OpenInputDesktop和GetUserObjectInformation当前的活动桌面,然后通过SetThreadDesktop设置线程桌面)

 

// RemoteControlService.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "RemoteControlService.h"
#include <Winsvc.h>
#include "CommonClas.h"


#ifdef _DEBUG
#define new DEBUG_NEW
#endif


TCHAR szServiceName[] = _T("Win8 Server");

DWORD dwThreadID;
HANDLE hEvent = INVALID_HANDLE_VALUE;
SERVICE_STATUS status;
SERVICE_STATUS_HANDLE hServiceStatus;


void Init();
BOOL IsServiceInstalled();
BOOL InstallService();
BOOL UninstallService();
BOOL ServiceCtrlStart();
BOOL ServiceCtrlStop();
void WINAPI ServiceMain();
void WINAPI ServiceStrl(DWORD dwOpcode);
BOOL RunRemoteControl();


// The one and only application object

CWinApp theApp;

using namespace std;

int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
 int nRetCode = 0;

 // initialize MFC and print and error on failure
 if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0))
 {
  // TODO: change error code to suit your needs
  _tprintf(_T("Fatal Error: MFC initialization failed\n"));
  nRetCode = 1;
 }
 else
 {
  // TODO: code your application's behavior here.
 }

 Init();

 dwThreadID = ::GetCurrentThreadId();

 SERVICE_TABLE_ENTRY st[] =
 {
  { szServiceName, (LPSERVICE_MAIN_FUNCTION)ServiceMain },
  { NULL, NULL }
 };

 TCHAR *lpCmdLine = argv[1];
 if ( argc == 2 )
 {
  BOOL bRet;

  if (wcsicmp(lpCmdLine, L"/install") == 0)
  {
   bRet = InstallService();
   if ( bRet == TRUE )
   {
    printf( "Install service %s success", szServiceName );
   }
   else
   {
    printf( "Install service %s failed", szServiceName );
   }
  }
  else if (wcsicmp(lpCmdLine, L"/uninstall") == 0)
  {
   bRet = UninstallService();
   if ( bRet == TRUE )
   {
    printf( "Uninstall service %s success", szServiceName );
   }
   else
   {
    printf( "Uninstall service %s failed", szServiceName );
   }

   // 杀掉进程
   CToolFunction::bProcessExist(_T("Win8_Server.exe"), TRUE);

  }
  else if (wcsicmp(lpCmdLine, L"/start") == 0)
  {
   bRet = ServiceCtrlStart();

   if ( bRet == TRUE )
   {
    printf( "Start service %s success", szServiceName );
   }
   else
   {
    printf( "Start service %s failed", szServiceName );
   }
  }
  else if (wcsicmp(lpCmdLine, L"/stop") == 0)
  {
   bRet = ServiceCtrlStop();
   if ( bRet == TRUE )
   {
    printf( "Stop service %s success", szServiceName );
   }
   else
   {
    printf( "Stop service %s failed", szServiceName );
   }
  }
  else
  {
   if (!::StartServiceCtrlDispatcher(st))
   {
    //LogEvent(_T("Register Service Main Function Error!"));
   }
  }
 }
 else
 {
  if (!::StartServiceCtrlDispatcher(st))
  {
   //LogEvent(_T("Register Service Main Function Error!"));
  }
 }

 return nRetCode;
}

// 功能描述:初始化相关结构
void Init()
{
 hServiceStatus = NULL;
 status.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
 status.dwCurrentState = SERVICE_STOPPED;
 status.dwControlsAccepted = SERVICE_ACCEPT_STOP;
 status.dwWin32ExitCode = 0;
 status.dwServiceSpecificExitCode = 0;
 status.dwCheckPoint = 0;
 status.dwWaitHint = 0;
}

// 功能描述:启动第三方程序
BOOL RunRemoteControl()
{
 HANDLE              hToken;
 HDESK               hdesk;
 HWINSTA             hwinsta;
 PROCESS_INFORMATION pi;
 STARTUPINFO         si;

 //HANDLE hExp = GetProcessHandle(L"EXPLORER.EXE");
 HANDLE hExp = CToolFunction::GetProcessHandle(L"Winlogon.exe");
 while (hExp == NULL)
 {
  hExp = CToolFunction::GetProcessHandle(L"Winlogon.exe");
  Sleep(100);
 }

 OpenProcessToken(hExp, TOKEN_ALL_ACCESS, &hToken);
 if(hToken == NULL)
 {
  return FALSE;
 }

 HWND hDesk = GetDesktopWindow();
 // BOOL bOk = ImpersonateLoggedOnUser(hToken);
 // GenericLog(Info,"ImpersonateLoggedOnUser %s",bOk?"Ok":"Failed");
 //GenericLog(Info,"Desktop HWND %s",(hDesk == GetDesktopWindow())?"Equal":"Not Equal");

 // obtain a handle to the interactive windowstation
 hwinsta = OpenWindowStation( _T("winsta0"), FALSE, READ_CONTROL|WRITE_DAC );
 if (hwinsta == NULL)
 {
  return FALSE;
 }

 HWINSTA hwinstaold = GetProcessWindowStation(); 
 if (!SetProcessWindowStation(hwinsta))
 {
  return FALSE;
 }

 // obtain a handle to the "default" desktop
 hdesk = OpenDesktop(
  _T("Winlogon"),
  0,
  FALSE,
  READ_CONTROL | WRITE_DAC |
  DESKTOP_WRITEOBJECTS | DESKTOP_READOBJECTS
  );
 if (hdesk == NULL)
 {
  return FALSE;
 }

 // close the handles to the interactive windowstation and desktop
 CloseWindowStation(hwinsta);
 CloseDesktop(hdesk);

 ZeroMemory(&si, sizeof(STARTUPINFO));
 si.cb        = sizeof(STARTUPINFO);
 si.lpDesktop = _T("winsta0\\Winlogon");

 TCHAR szParameter[10] = {0};
 if(CreateProcessAsUser(hToken, CToolFunction::oGetCurPath()+_T("\\Win8_Server.exe"), szParameter, NULL, NULL, FALSE, CREATE_NO_WINDOW, NULL, NULL, &si, &pi))
 {
  CloseHandle(pi.hProcess);
  CloseHandle(pi.hThread);
 }

 SetProcessWindowStation(hwinstaold);

 return TRUE;
}

// 功能描述:服务主线程函数,既用户选择开启服务时调用的函数
void WINAPI ServiceMain()
{
 // Register the control request handler
 status.dwCurrentState = SERVICE_START_PENDING;
 status.dwControlsAccepted = SERVICE_ACCEPT_STOP;

 //注册服务控制
 hServiceStatus = RegisterServiceCtrlHandler(szServiceName, ServiceStrl);
 if (hServiceStatus == NULL)
 {
  return;
 }

 SetServiceStatus(hServiceStatus, &status);

 //如下代码可以为启动服务前的准备工作
 hEvent = ::CreateEvent( NULL, TRUE, FALSE, NULL );
 if ( hEvent == NULL )
 {
  status.dwCurrentState = SERVICE_STOPPED;
  SetServiceStatus(hServiceStatus, &status);
  return;
 }

 //更改服务状态为启动
 status.dwWin32ExitCode = S_OK;
 status.dwCheckPoint = 0;
 status.dwWaitHint = 0;
 status.dwCurrentState = SERVICE_RUNNING;
 SetServiceStatus(hServiceStatus, &status);

 //等待用户选择停止服务,
 //当然你也可以把你的服务代码用线程来执行,
 //此时这里只需等待线程结束既可。

 // 启动第三方程序
 RunRemoteControl();

 while ( WaitForSingleObject( hEvent, 3000 ) != WAIT_OBJECT_0 )
 {
  if (!CToolFunction::bProcessExist(_T("Win8_Server.exe")))
  {
   // 启动第三方程序
   RunRemoteControl();
  }
 }

 //
 //停止服务
 status.dwCurrentState = SERVICE_STOPPED;
 SetServiceStatus(hServiceStatus, &status);
}

// 功能描述:服务控制函数
void WINAPI ServiceStrl(DWORD dwOpcode)
{
 switch (dwOpcode)
 {
  case SERVICE_CONTROL_STOP:
   status.dwCurrentState = SERVICE_STOP_PENDING;
   SetServiceStatus(hServiceStatus, &status);

   //告诉服务线程停止工作
   ::SetEvent( hEvent );
   break;

  case SERVICE_CONTROL_PAUSE:

   break;

  case SERVICE_CONTROL_CONTINUE:

   break;

  case SERVICE_CONTROL_INTERROGATE:

   break;

  case SERVICE_CONTROL_SHUTDOWN:

   break;

  default:
   ;
 }
}


// 功能描述:判断服务是否已安装
BOOL IsServiceInstalled()
{
 BOOL bResult = FALSE;

 //打开服务控制管理器
 SC_HANDLE hSCM = ::OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
 if (hSCM != NULL)
 {
  //打开服务
  SC_HANDLE hService = ::OpenService(hSCM, szServiceName, SERVICE_QUERY_CONFIG);
  if (hService != NULL)
  {
   bResult = TRUE;
   ::CloseServiceHandle(hService);
  }

  ::CloseServiceHandle(hSCM);
 }

 return bResult;
}


// 功能描述:安装服务
BOOL InstallService()
{
 if (IsServiceInstalled())
  return TRUE;

 //打开服务控制管理器
 SC_HANDLE hSCM = ::OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
 if (hSCM == NULL)
 {
  return FALSE;
 }

 // Get the executable file path
 TCHAR szFilePath[MAX_PATH];
 ::GetModuleFileName(NULL, szFilePath, MAX_PATH);

 //创建服务
 SC_HANDLE hService = ::CreateService(
  hSCM,
  szServiceName,
  szServiceName,
  SERVICE_ALL_ACCESS,
  SERVICE_WIN32_OWN_PROCESS|SERVICE_INTERACTIVE_PROCESS,
  SERVICE_AUTO_START, //如果为SERVICE_DEMAND_START则表示此服务需手工启动
  SERVICE_ERROR_NORMAL,
  szFilePath,
  NULL,
  NULL,
  _T("RPCSS\0"),
  NULL,
  NULL);

 if (hService == NULL)
 {
  ::CloseServiceHandle(hSCM);
  return FALSE;
 }

 ::CloseServiceHandle(hService);
 ::CloseServiceHandle(hSCM);

 return TRUE;
}

// 功能描述:删除服务
BOOL UninstallService()
{
 if (!IsServiceInstalled())
  return TRUE;

 SC_HANDLE hSCM = ::OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
 if (hSCM == NULL)
 {
  return FALSE;
 }

 SC_HANDLE hService = ::OpenService(hSCM, szServiceName, SERVICE_STOP | DELETE);
 if (hService == NULL)
 {
  ::CloseServiceHandle(hSCM);
  return FALSE;
 }

 SERVICE_STATUS status;
 ::ControlService(hService, SERVICE_CONTROL_STOP, &status);

 // 删除服务
 BOOL bDelete = ::DeleteService(hService);
 ::CloseServiceHandle(hService);
 ::CloseServiceHandle(hSCM);

 if (bDelete)
  return TRUE;

 //LogEvent(_T("Service could not be deleted"));

 return FALSE;
}

// 功能描述:开启服务
BOOL ServiceCtrlStart()
{
 BOOL bRet;
 SC_HANDLE hSCM;
 SC_HANDLE hService;


 hSCM=OpenSCManager(NULL,NULL,SC_MANAGER_CONNECT);
 if (hSCM!=NULL)
 {
  hService=OpenService( hSCM, szServiceName, SERVICE_START);
  if (hService!=NULL)
  {
   //开始Service
   bRet = StartService(hService,0,NULL);
   CloseServiceHandle(hService);
  }
  else
  {
   bRet = FALSE;
  }

  CloseServiceHandle(hSCM);
 }
 else
 {
  bRet = FALSE;
 }

 return bRet;
}

// 功能描述:停止服务
BOOL ServiceCtrlStop()
{
 BOOL bRet;
 SC_HANDLE hSCM;
 SC_HANDLE hService;
 SERVICE_STATUS ServiceStatus;

 hSCM=OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS );
 if (hSCM!=NULL)
 {
  hService=OpenService( hSCM, szServiceName, SERVICE_STOP|SERVICE_QUERY_STATUS );
  if (hService!=NULL)
  {
   QueryServiceStatus( hService, &ServiceStatus );

   if (ServiceStatus.dwCurrentState == SERVICE_RUNNING)
   {
    bRet = ControlService( hService, SERVICE_CONTROL_STOP, &ServiceStatus );
   }
   else
   {
    bRet = FALSE;
   }

   CloseServiceHandle( hService );
  }
  else
  {
   bRet = FALSE;
  }

  CloseServiceHandle( hSCM );
 }
 else
 {
  bRet = FALSE;
 }

 return bRet;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值