您的位置:首页 > 其它

如何创建一个Service

2014-07-14 18:42 288 查看
这边文章简单的向大家介绍一下如何用ATL 创建一个Service。

我用的是Visual studio 2010。

首先从VS2010中选择File -> New -> Project... 。选择Visual C++ -> ATL -> ATL Project。

写好Name,点击OK。再点击Next。然后选择Service(EXE),点击Finish。

这时你会发现一个空的Service就已经被创建了。然后里面只有两个函数。_tWinMain 和InitializeSecurity

明显只有这两个函数是不够的。因此还须添加其他一些函数。具体请看以下全部CPP内的代码。只需更改CPP内代码,就完成了。

// TestService.cpp : Implementation of WinMain

#include <stdio.h>
#include "stdafx.h"
#include "resource.h"
#include "TestService_i.h"

#define SERVICE_NAME  _T("Test Service")
#define SERVICE_DESC  _T("Test Service")

const TCHAR REG_KEY_TESTSRV[] = _T("SYSTEM\\CurrentControlSet\\Services\\Test Service");

class CTestServiceModule : public ATL::CAtlServiceModuleT< CTestServiceModule, IDS_SERVICENAME >
{
public :
DECLARE_LIBID(LIBID_TestServiceLib)
DECLARE_REGISTRY_APPID_RESOURCEID(IDR_TESTSERVICE, "{6F4B5E0D-EBCC-472C-AD6A-897DC5BA19A1}")
HRESULT InitializeSecurity() throw()
{
// TODO : Call CoInitializeSecurity and provide the appropriate security settings for your service
// Suggested - PKT Level Authentication,
// Impersonation Level of RPC_C_IMP_LEVEL_IDENTIFY
// and an appropiate Non NULL Security Descriptor.

HRESULT hResult = CoInitializeSecurity(
NULL,-1,NULL,NULL,
RPC_C_AUTHN_LEVEL_DEFAULT,
RPC_C_IMP_LEVEL_IMPERSONATE,
NULL,EOAC_NONE,NULL);
if(FAILED(hResult)){
return FALSE;
}

return S_OK;
}

HRESULT RegisterAppId(bool bService = false) throw()
{
if (!Uninstall()) {
return E_FAIL;
}

HRESULT hr = UpdateRegistryAppId(TRUE);
if (FAILED(hr)) {
return hr;
}

CRegKey keyAppID;
LONG lRes = keyAppID.Open(HKEY_CLASSES_ROOT, _T("AppID"), KEY_WRITE);
if (lRes != ERROR_SUCCESS) {
return AtlHresultFromWin32(lRes);
}

CRegKey key;
lRes = key.Create(keyAppID, GetAppIdT());
if (lRes != ERROR_SUCCESS) {
return AtlHresultFromWin32(lRes);
}

key.DeleteValue(_T("LocalService"));

if (!bService)
return S_OK;

key.SetStringValue(_T("LocalService"), m_szServiceName);

// Create service
if (!Install()) {
return E_FAIL;
}
return S_OK;
}

BOOL Install() throw()
{
if (IsInstalled()) {
return TRUE;
}

// Get the executable file path
TCHAR szFilePath[MAX_PATH + _ATL_QUOTES_SPACE];
DWORD dwFLen = ::GetModuleFileName(NULL, szFilePath + 1, MAX_PATH);
if( dwFLen == 0 || dwFLen == MAX_PATH ) {
return FALSE;
}

// Quote the FilePath before calling CreateService
szFilePath[0] = _T('\"');
szFilePath[dwFLen + 1] = _T('\"');
szFilePath[dwFLen + 2] = 0;

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

SC_HANDLE hService = ::CreateService(
hSCM, m_szServiceName, m_szServiceName,
SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS,
SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL,
szFilePath, NULL, NULL, _T("Winmgmt\0\0"), NULL, NULL);

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

//Service Settings
if(!UpdateServiceSetting(hService,szFilePath))
{
::CloseServiceHandle(hSCM);
return FALSE;
}

::CloseServiceHandle(hService);
::CloseServiceHandle(hSCM);
return TRUE;
}

int WinMain(HINSTANCE hInstance) throw()
{
HRESULT hr = S_OK;

LPTSTR lpCmdLine = GetCommandLine();
if (ParseCommandLine(lpCmdLine, &hr) == true) {
hr = Start(hInstance);
}

return hr;
}

HRESULT Start(HINSTANCE hInstance) throw()
{

CRegKey keyAppID;
LONG lRes = keyAppID.Open(HKEY_CLASSES_ROOT, _T("AppID"), KEY_READ);
if (lRes != ERROR_SUCCESS)
{
m_status.dwWin32ExitCode = lRes;
return m_status.dwWin32ExitCode;
}

CRegKey key;
lRes = key.Open(keyAppID, GetAppIdT(), KEY_READ);
if (lRes != ERROR_SUCCESS)
{
m_status.dwWin32ExitCode = lRes;
return m_status.dwWin32ExitCode;
}

TCHAR szValue[MAX_PATH];
DWORD dwLen = MAX_PATH;
lRes = key.QueryStringValue(_T("LocalService"), szValue, &dwLen);

m_bService = FALSE;
if (lRes == ERROR_SUCCESS)
m_bService = TRUE;

if (m_bService)
{
SERVICE_TABLE_ENTRY st[] =
{
{ m_szServiceName, _ServiceMain },
{ NULL, NULL }
};
if (::StartServiceCtrlDispatcher(st) == 0)
m_status.dwWin32ExitCode = GetLastError();
return m_status.dwWin32ExitCode;
}

// local server - call Run() directly, rather than
// from ServiceMain()
m_status.dwWin32ExitCode = Run(hInstance);
return m_status.dwWin32ExitCode;
}

void ServiceMain(DWORD dwArgc, LPTSTR* lpszArgv) throw()
{
lpszArgv;
dwArgc;
// Register the control request handler
m_status.dwCurrentState = SERVICE_START_PENDING;
m_status.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN;
m_hServiceStatus = RegisterServiceCtrlHandler(m_szServiceName, _Handler);
if (m_hServiceStatus == NULL)
{
//LogEvent(_T("Handler not installed"));
return;
}
SetServiceStatus(SERVICE_START_PENDING);

m_status.dwWin32ExitCode = S_OK;
m_status.dwCheckPoint = 0;
m_status.dwWaitHint = 0;

#ifndef _ATL_NO_COM_SUPPORT

HRESULT hr = E_FAIL;
hr = InitializeCom();
if (FAILED(hr))
{
// Ignore RPC_E_CHANGED_MODE if CLR is loaded. Error is due to CLR initializing
// COM and InitializeCOM trying to initialize COM with different flags.
if (hr != RPC_E_CHANGED_MODE || GetModuleHandle(_T("Mscoree.dll")) == NULL)
{
return;
}
}
else
{
m_bComInitialized = true;
}

m_bDelayShutdown = false;
#endif //_ATL_NO_COM_SUPPORT
// When the Run function returns, the service has stopped.
m_status.dwWin32ExitCode = Run(SW_HIDE);

#ifndef _ATL_NO_COM_SUPPORT
if (m_bService && m_bComInitialized)
UninitializeCom();
#endif

SetServiceStatus(SERVICE_STOPPED);
//LogEvent(_T("Service stopped"));
}

HRESULT Run(HINSTANCE hInstance) throw()
{
HRESULT hr = S_OK;

hr = PreMessageLoop(SW_HIDE);

if (hr == S_OK)
{
if (m_bService)
{
//LogEvent(_T("Service started"));
SetServiceStatus(SERVICE_RUNNING);
}

RunMessageLoop(hInstance);
}

if (SUCCEEDED(hr))
{
hr = PostMessageLoop();
}

return hr;
}

HRESULT PreMessageLoop(int nShowCmd) throw()
{
HRESULT hr = __super::PreMessageLoop(SW_HIDE);

#if _ATL_VER >= 0x0700
if (SUCCEEDED(hr) && !m_bDelayShutdown)
hr = CoResumeClassObjects();
#endif
return hr;
}

void RunMessageLoop(HINSTANCE hInstance) throw()
{
MSG msg;
while (GetMessage(&msg, 0, 0, 0) > 0)
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}

}

HRESULT PostMessageLoop()
{
return __super::PostMessageLoop();
}

void OnStop() throw()
{

SetServiceStatus(SERVICE_STOPPED);
__super::OnStop();
}

void OnShutdown() throw()
{

SetServiceStatus(SERVICE_STOPPED);
__super::OnShutdown();
}

BOOL UpdateServiceSetting(SC_HANDLE hService,LPCTSTR lpszFilePath)
{
if(!ChangeServiceConfig(
hService,
SERVICE_WIN32_OWN_PROCESS,
SERVICE_AUTO_START,
SERVICE_ERROR_NORMAL,
lpszFilePath,
NULL,NULL,NULL,NULL,NULL,
SERVICE_NAME)){
return FALSE;
}

CRegKey keyTestService;
LONG lRes = keyTestService.Open(HKEY_LOCAL_MACHINE, REG_KEY_TESTSRV, KEY_WRITE);
if (lRes != ERROR_SUCCESS){
return FALSE;
}
keyTestService.SetStringValue(_T("Description"), SERVICE_DESC);
keyTestService.Close();

return TRUE;
}
};

CTestServiceModule _AtlModule;

//
extern "C" int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE /*hPrevInstance*/,
LPTSTR /*lpCmdLine*/, int /*nShowCmd*/)
{
return _AtlModule.WinMain(hInstance);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: