Click here to Skip to main content
Click here to Skip to main content
Add your own
alternative version
Go to top

Remote Control PCs

, 20 Sep 2013
Two projects that work together to remote control PCs across a LAN.
#include "stdafx.h"
#include "..\Common.h"
#include "Service.h"
#include <aclapi.h>

CControlService::CControlService(const TCHAR * pszServiceName) : m_hSCM(NULL), m_hService(NULL)
{
	// Open the SCM
	m_hSCM = OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS);
	if (m_hSCM)
	{
		if (pszServiceName)
			Open(pszServiceName);
	}
}

CControlService::~CControlService()
{
	Close();
}

bool CControlService::Open(const TCHAR * pszServiceName)
{
	try
	{
		if (IsOpen())
			Close();
		if (m_hSCM && pszServiceName)
		{
			// Open the service
			m_hService = OpenService(m_hSCM,pszServiceName,SC_MANAGER_ALL_ACCESS | SERVICE_INTERROGATE | SERVICE_USER_DEFINED_CONTROL);
			if (m_hService)
				return true;
		}
	}
	catch (...)
	{
	}
	return false;
}

void CControlService::Close()
{
	try
	{
		// Close the service
		if (m_hService)
		{
			CloseServiceHandle(m_hService);
			m_hService = NULL;
		}
	}
	catch (...)
	{
	}
}

// Test for the service being open and available for controlling or querying
bool CControlService::IsOpen()
{
	return m_hService != NULL ? true : false;
}

// Test the service for availability
bool CControlService::IsAvailable()
{
	bool bFlag = false;
	if (IsOpen())
	{
		// Query the service
		DWORD dwQuery = Query();
		switch (dwQuery)
		{
		case ERROR_SERVICE_NOT_ACTIVE:
		case SERVICE_STOPPED:
		case SERVICE_START_PENDING:
		case SERVICE_STOP_PENDING:
		case SERVICE_RUNNING:
		case SERVICE_CONTINUE_PENDING:
		case SERVICE_PAUSE_PENDING:
		case SERVICE_PAUSED:
			bFlag = true;
			break;
		default:
			break;
		}
	}
	return bFlag;
}

// Test the service for being in a running state
bool CControlService::IsRunning()
{
	bool bFlag = false;
	if (IsOpen())
	{
		// Query the service
		DWORD dwQuery = Query();
		switch (dwQuery)
		{
		case SERVICE_RUNNING:
			bFlag = true;
			break;
		default:
			break;
		}
	}
	return bFlag;
}

// Test the service for being in a paused state
bool CControlService::IsPaused()
{
	bool bFlag = false;
	if (IsOpen())
	{
		// Query the service
		DWORD dwQuery = Query();
		switch (dwQuery)
		{
		case SERVICE_PAUSED:
			bFlag = true;
			break;
		default:
			break;
		}
	}
	return bFlag;
}

// Test the service for being in a stopped state
bool CControlService::IsStopped()
{
	bool bFlag = false;
	if (IsOpen())
	{
		// Query the service
		DWORD dwQuery = Query();
		switch (dwQuery)
		{
		case SERVICE_STOPPED:
		case ERROR_SERVICE_NOT_ACTIVE:
			bFlag = true;
			break;
		default:
			break;
		}
	}
	return bFlag;
}

// Test the service for being in a pending state
bool CControlService::IsPending()
{
	bool bFlag = false;
	if (IsOpen())
	{
		// Query the service
		DWORD dwQuery = Query();
		switch (dwQuery)
		{
		case SERVICE_START_PENDING:
		case SERVICE_STOP_PENDING:
		case SERVICE_CONTINUE_PENDING:
		case SERVICE_PAUSE_PENDING:
			bFlag = true;
			break;
		default:
			break;
		}
	}
	return bFlag;
}

// Start the service
bool CControlService::Start()
{
	bool bFlag = false;
	if (IsOpen())
	{
		// Start the service
		bFlag = StartService(m_hService,0,NULL) ? true : false;
	}
	return bFlag;
}

// Stop the service
DWORD CControlService::Stop()
{
	return Control(SERVICE_CONTROL_STOP);
}

// Pause the service
DWORD CControlService::Pause()
{
	return Control(SERVICE_CONTROL_PAUSE);
}

// Continue the service
DWORD CControlService::Continue()
{
	return Control(SERVICE_CONTROL_CONTINUE);
}

// Synchronize the service to receive a named pipe connection
DWORD CControlService::UserSync(DWORD dwOp)
{
	return Control(SERVICE_CONTROL_USER + dwOp);
}

// Query the service status
DWORD CControlService::Query()
{
	return Control(SERVICE_CONTROL_INTERROGATE);
}

// Control or query the service
DWORD CControlService::Control(DWORD dwControl)
{
	DWORD dwRet = ERROR_ACCESS_DENIED;
	try
	{
		if (IsOpen())
		{
			// Intialize the service status
			SERVICE_STATUS ServiceStatus;
			memset(&ServiceStatus,0,sizeof(ServiceStatus));
			if (ControlService(m_hService,dwControl,&ServiceStatus))
			{
				dwRet = ServiceStatus.dwCurrentState;
				switch (dwRet)
				{
				case SERVICE_STOPPED:
					DebugMsg("The service is not running\n");
					break;
				case SERVICE_START_PENDING:
					DebugMsg("The service is starting\n");
					break;
				case SERVICE_STOP_PENDING:
					DebugMsg("The service is stopping\n");
					break;
				case SERVICE_RUNNING:
					DebugMsg("The service is running\n");
					break;
				case SERVICE_CONTINUE_PENDING:
					DebugMsg("The service continue is pending\n");
					break;
				case SERVICE_PAUSE_PENDING:
					DebugMsg("The service pause is pending\n");
					break;
				case SERVICE_PAUSED:
					DebugMsg("The service is paused\n");
					break;
				case ERROR_SERVICE_NOT_ACTIVE:
					DebugMsg("The service is not active\n");
					break;
				default:
					DebugMsg("The service returned code %d\n",dwRet);
					break;
				}
			}
			else
			{
				dwRet = GetLastError();
				DebugLastError();
			}
		}
	}
	catch (...)
	{
	}
	return dwRet;
}

// Install the service
bool CControlService::Install(const TCHAR * pszServiceName, const TCHAR * pszDescription, const TCHAR * pszFileName)
{
	bool bInstall = false;
	if (m_hSCM && !IsOpen())
	{
		// Create the service
		m_hService = CreateService(m_hSCM,pszServiceName,pszServiceName,SERVICE_ALL_ACCESS,SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS,SERVICE_AUTO_START,SERVICE_ERROR_NORMAL,pszFileName,NULL,NULL,NULL,NULL,NULL);
		if (m_hService)
		{
			// Set the description of the service
			SERVICE_DESCRIPTION Desc;
			Desc.lpDescription = (LPSTR)pszDescription;
			ChangeServiceConfig2(m_hService,SERVICE_CONFIG_DESCRIPTION,&Desc);
			bInstall = true;
		}
	}
	return bInstall;
}

// Remove the service
bool CControlService::Remove(const TCHAR * pszServiceName)
{
	bool bRemove = false;
	if (m_hSCM)
	{
		if (!IsOpen())
			Open(pszServiceName);
		if (IsOpen())
		{
			if (DeleteService(m_hService)) 
			{
				Close();
				bRemove = true;
			}
		}
	}
	return bRemove;
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The GNU General Public License (GPLv3)

Share

About the Author

Andy Bantly
Founder
United States United States
Working as a software developer since 1989. Started out with Basic, FORTRAN and JCL, moved into Visual Basic 1.0, C, then C++, and now I work mainly in C++ using MFC, Win32, and ATL/COM. I use Microsoft Products only because that is what gives me gainful employment. Through work, I have a lot of experience with HTML, JavaScript, XSL transformations, the XMLHTTP object, PHP 4.x, and simple COM object integrations.
 
I've worked for the University of Oklahoma in the school of meteorology (Go SOONERS!), consulting, and now as a Senior Software Engineer. These things keep my lights on and electricity going. My dream job is to own a bowling alley and rub elbows with pro-bowlers! I'm also an avid pedicab driver and have my own cab. I like the hustle of picking up people in downtown and biking them to their destination.
Follow on   Google+   LinkedIn

| Advertise | Privacy | Mobile
Web04 | 2.8.140916.1 | Last Updated 20 Sep 2013
Article Copyright 2000 by Andy Bantly
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid