zoukankan      html  css  js  c++  java
  • svchost服务(DLL服务)

        相比于exe服务,DLL服务只需要一个dll,而且运行是通过svchost.exe来运行的,同时安装和卸载的时候需要自己手动修改相关注册表。原理及其细节就不多说了,直接上代码吧(我写的这个是创建新组然后在里面创建新服务的,为了防止刚刚注册的服务因为在别的组里而导致必须下次重启才能启动服务的问题)。


    // SvcDll.cpp : 定义 DLL 应用程序的导出函数。
    //
    #include "stdafx.h"
    #include <string>
    #include <Strsafe.h>
    #include <windows.h>
    
    using namespace std;
    
    #pragma comment(lib,"Advapi32.lib")
    #pragma warning(disable:4996)
    
    HMODULE  g_hMyself;
    DWORD					dwCurrState;
    SERVICE_STATUS_HANDLE	hSrv;	
    
    int		TellSCM					( DWORD dwState, DWORD dwExitCode, DWORD dwProgress );
    void		WINAPI ServiceMain		( int argc, wchar_t* argv[] );
    void		__stdcall ServiceHandler( DWORD dwCommand );
    DWORD WINAPI proc_thread(LPVOID lparam);
    
    
    void Startup()
    {
    	CreateThread(NULL,NULL,proc_thread,NULL,NULL,NULL);
    }
    
    void WINAPI ServiceMain( int argc, wchar_t* argv[] )
    {
    	OutputDebugStringA("ServiceMain Load");
    	TCHAR svcname[256];
    	wcsncpy(svcname,argv[0] ,256);
    	hSrv = RegisterServiceCtrlHandler( svcname, (LPHANDLER_FUNCTION)ServiceHandler );
    	if( hSrv == NULL )
    	{
    		OutputDebugStringA("SvcHostDLL RegisterServiceCtrlHandler failed");
    		return;
    	}else FreeConsole();
    
    	TellSCM( SERVICE_START_PENDING, 0, 1 );
    	TellSCM( SERVICE_RUNNING, 0, 0 );
    
    	Startup();
    
    	return;
    }
    
    
    int TellSCM( DWORD dwState, DWORD dwExitCode, DWORD dwProgress )
    {
    	SERVICE_STATUS srvStatus;
    	srvStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
    	srvStatus.dwCurrentState = dwCurrState = dwState;
    	srvStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_PAUSE_CONTINUE | SERVICE_ACCEPT_SHUTDOWN;
    	srvStatus.dwWin32ExitCode = dwExitCode;
    	srvStatus.dwServiceSpecificExitCode = 0;
    	srvStatus.dwCheckPoint = dwProgress;
    	srvStatus.dwWaitHint = 3000;
    	return SetServiceStatus( hSrv, &srvStatus );
    }
    
    BOOL Is64Sys(){
    	SYSTEM_INFO si;
    	GetNativeSystemInfo(&si);
    
    	if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64
    		|| si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_IA64)
    		return TRUE;
    	else
    		return FALSE;
    }
    
    BOOL InstallService(const wstring &wsDllFilePath ,const wstring  &wsSvcName ,const wstring &wsDescribe){
    
    //Modify registry related
    	wstring wsSvcGroupName = wstring(wsSvcName) + L"GroupEx";
    	HKEY hRoot = NULL;
    	if(ERROR_SUCCESS != RegOpenKeyEx(
    		HKEY_LOCAL_MACHINE,
    		L"SOFTWARE\Microsoft\Windows NT\CurrentVersion\Svchost",
    		0,
    		KEY_QUERY_VALUE | KEY_SET_VALUE,
    		&hRoot)){		
    			return FALSE;
    	}
    	if(ERROR_SUCCESS != RegSetValueEx(
    		hRoot,
    		wsSvcGroupName.c_str(),
    		0,
    		REG_MULTI_SZ,
    		(const BYTE *)wsSvcName.c_str(),
    		(wsSvcName.length() + 1)  * sizeof(WCHAR))){
            return FALSE;
    	}
    	CloseHandle(hRoot);
    //install service
         SC_HANDLE hscm = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
     	 if (hscm == NULL){
    		 return FALSE;
    	 }
    	wchar_t wszBinPath[MAX_PATH] = { 0 };
    	if (Is64Sys()){
    		GetSystemWow64Directory(wszBinPath, MAX_PATH);
    		StringCchCat(wszBinPath, MAX_PATH, L"\svchost.exe -k ");
    	}
    	else{
    		GetSystemDirectory(wszBinPath, MAX_PATH);
    		StringCchCat(wszBinPath, MAX_PATH, L"\svchost.exe -k ");
    	}
    	StringCchCat(wszBinPath, MAX_PATH, wsSvcGroupName.c_str());
    	 
    	SC_HANDLE scHService  = CreateService( 
    		hscm,                        // SCManager database 
    		wsSvcName.c_str(),                    // name of service 
    		NULL,           // service name to display 
    		SERVICE_ALL_ACCESS,        // desired access 
    		SERVICE_WIN32_SHARE_PROCESS, // service type 
    		SERVICE_AUTO_START,      // start type 
    		SERVICE_ERROR_NORMAL,      // error control type 
    		wszBinPath,         // service's binary 
    		NULL,                      // no load ordering group 
    		NULL,                      // no tag identifier 
    		NULL,                      // no dependencies 
    		NULL,                      // LocalSystem account 
     		NULL);                     // no password 
     		if (scHService == NULL){
     			return FALSE;
     		}
           
    //config service
    		wstring wsRegPath = L"SYSTEM\CurrentControlSet\Services\" + wsSvcName;
     		if(ERROR_SUCCESS != RegOpenKeyEx(HKEY_LOCAL_MACHINE, wsRegPath.c_str(), 
    			0, KEY_ALL_ACCESS, &hRoot)){
    				return FALSE;
    		}
    		HKEY hSubKey = NULL; 
            if(ERROR_SUCCESS != RegCreateKey(hRoot, L"Parameters", &hSubKey)){
    			return FALSE;
    		}
    		if(ERROR_SUCCESS != RegSetValueEx(hSubKey, L"ServiceDll", 0, REG_EXPAND_SZ,
    			(unsigned char*)wsDllFilePath.c_str(), (wsDllFilePath.length() + 1)*sizeof(wchar_t))){
    				return FALSE;
    		}
    		StartService(scHService, 0, NULL);
    		CloseHandle(hRoot);
    		CloseHandle(hSubKey);
    		CloseServiceHandle(scHService); 
    		CloseServiceHandle(hscm); 
            return TRUE;
    }
    
    bool DeleteService(const wstring &wsServiceName) { 
    	HANDLE schSCManager; 
    	SC_HANDLE hService; 
    	schSCManager = OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS); 
    	if (schSCManager == NULL)  return false;
    
    	hService=OpenService((struct SC_HANDLE__ *)schSCManager,wsServiceName.c_str(),SERVICE_ALL_ACCESS); 
    	if (hService == NULL)  return false; 
    
    	SERVICE_STATUS status;
    	QueryServiceStatus(hService, &status);  // 获得服务的当前状态
    
    	if(::DeleteService(hService)==0) return false;
    	if(CloseServiceHandle(hService)==0) return false; 
    
    	return true; 
    }
    
    bool StopService(const wstring &wsServiceName){
    	HANDLE schSCManager; 
    	SC_HANDLE hService; 
    	schSCManager = OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS); 
    	if (schSCManager == NULL)  return false;
    
    	hService=OpenService((struct SC_HANDLE__ *)schSCManager,wsServiceName.c_str(),SERVICE_ALL_ACCESS); 
    	if (hService == NULL)  return false; 
    
    	SERVICE_STATUS status;
    	QueryServiceStatus(hService, &status);  // 获得服务的当前状态
    	if (status.dwCurrentState != SERVICE_STOPPED)   // 如果服务不处于停止状态,则将其状态设置为
    		//停止状态
    			ControlService(hService,SERVICE_CONTROL_STOP, &status);
    
    	return true;
    }
    
    
    void __stdcall ServiceHandler( DWORD dwCommand )
    {
    	switch( dwCommand )
    	{
    	case SERVICE_CONTROL_STOP:
    		TellSCM( SERVICE_STOP_PENDING, 0, 1 );
    		TellSCM( SERVICE_STOPPED, 0, 0 );
    		break;
    	case SERVICE_CONTROL_PAUSE:
    		TellSCM( SERVICE_PAUSE_PENDING, 0, 1 );
    		TellSCM( SERVICE_PAUSED, 0, 0 );
    		break;
    	case SERVICE_CONTROL_CONTINUE:
    		TellSCM( SERVICE_CONTINUE_PENDING, 0, 1 );
    		TellSCM( SERVICE_RUNNING, 0, 0 );
    		break;
    	case SERVICE_CONTROL_INTERROGATE:
    		TellSCM( dwCurrState, 0, 0 );
    		break;
    	case SERVICE_CONTROL_SHUTDOWN:
    		TellSCM( SERVICE_STOPPED, 0, 0 );
    		break;
    	}
    }
    
    
    BOOL APIENTRY DllMain( HMODULE hModule,
    					  DWORD  ul_reason_for_call,
    					  LPVOID lpReserved
    					  )
    {
    	g_hMyself = hModule;
    	switch (ul_reason_for_call)
    	{
    	case DLL_PROCESS_ATTACH:
    	case DLL_THREAD_ATTACH:
    	case DLL_THREAD_DETACH:
    	case DLL_PROCESS_DETACH:
    		break;
    	}
    	return TRUE;
     }
    
    
    
    //********************************************************************************
    DWORD WINAPI proc_thread(LPVOID lparam)
    {
    	//do something
    	return 0;
    }
    
    wstring wsSvcName = L"Archer";
    
    VOID CALLBACK InsertSvc(){
    	WCHAR wcDllFilePatu[MAX_PATH] = {0};
    	GetModuleFileName(g_hMyself, wcDllFilePatu, MAX_PATH);
    	BOOL bResult = InstallService(wcDllFilePatu ,wsSvcName.c_str() ,wsSvcName.c_str());
    }
    
    VOID CALLBACK UninstallSvc(){
    	StopService(wsSvcName);
    	DeleteService(wsSvcName);
    	HKEY hKey;
    	LONG lResult = RegOpenKeyEx(HKEY_LOCAL_MACHINE, L"SOFTWARE\Wow6432Node\Microsoft\Windows NT\CurrentVersion\Svchost", 0,KEY_ALL_ACCESS, &hKey); 
    	if(ERROR_SUCCESS == lResult)
    	{
    		wstring wsSvcGroupName = wstring(wsSvcName) + L"GroupEx";
    		RegDeleteValue(hKey ,wsSvcGroupName.c_str());
    		RegCloseKey(hKey);
    	}
    }
    //********************************************************************************
    最后记得设置导出函数 def文件,或者是直接把需要导出的函数开始添加相关代码。

    我是设置的def文件。DllImport.def内容是


    EXPORTS
    ServiceMain
    InsertSvc
    UninstallSvc

    写了个测试例子,存在了这个位置,可以直接下载下来编译修改:

    http://download.csdn.net/detail/u013761036/9647008

  • 相关阅读:
    UItableView的cell重用机制
    iOS开发中常遇到的面试题
    iOS UIScrollView 的基本用法
    iOS的CocoaPods手动挡到自动挡到导入第三方框架 转发
    iOS之NSPredicate(正则表达式和UIBarController):谓词
    iOS UISearchController 搜索框
    PHP 基本用法及基本知识点
    iOS 九宫格的实现
    iOS XML 系统自带的解析方法
    iOS xml文件的解析方式 XMLDictionary,GDataXMLNode,NSXMLParser 转发自徒步天涯
  • 原文地址:https://www.cnblogs.com/csnd/p/12062233.html
Copyright © 2011-2022 走看看