相比于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

svchost服务(DLL服务)的更多相关文章

  1. 服务--web服务

    .面向对象和面向组件 .什么是Web服务 Web Service "Stack" .Web服务的应用分类 Web服务都是对象/组件技术在Internet中的延伸 面向对象和面向组件 ...

  2. [转]Windows服务“允许服务与桌面交互”的使用和修改方法

    上一篇文章是纯 C# 代码的形式勾上 “允许服务与桌面交互” 选项的 本文转载自:http://blog.csdn.net/lanruoshui/article/details/4756408 描述: ...

  3. .Net Core微服务系列--服务发现

    什么是服务发现 首先我们先思考一个问题,当我们在浏览器中输入一个域名比如baidu.com,然后发生了什么才能让我们访问到百度的网页?简单来说,浏览器会首先从主机的hosts文件中查看是否有baidu ...

  4. Oracle 11g必须开启的服务及服务详细介绍

    转自:http://www.educity.cn/shujuku/404120.html 成功安装Oracle  11g数据库后,你会发现自己电脑运行速度会变慢,配置较低的电脑甚至出现非常卡的状况,通 ...

  5. 玩转Windows服务系列——服务运行、停止流程浅析

    通过研究Windows服务注册卸载的原理,感觉它并没有什么特别复杂的东西,Windows服务正在一步步退去它那神秘的面纱,至于是不是美女,大家可要睁大眼睛看清楚了. 接下来研究一下Windows服务的 ...

  6. C#操作注册服务卸载服务启动服务停止服务.. .

    using Microsoft.Win32; using System; using System.Collections; using System.Collections.Generic; usi ...

  7. Oracle 11g必须开启的服务及服务详细介绍(转)

    成功安装Oracle 11g数据库后,你会发现自己电脑运行速度会变慢,配置较低的电脑甚至出现非常卡的状况,通过禁止非必须开启的Oracle服务可以提升电脑的运行速度.那么,具体该怎么做呢? 按照win ...

  8. Android(java)学习笔记229:服务(service)之绑定服务调用服务里面的方法 (采用接口隐藏代码内部实现)

    1.接口 接口可以隐藏代码内部的细节,只暴露程序员想暴露的方法 2.利用上面的思想优化之前的案例:服务(service)之绑定服务调用服务里面的方法,如下: (1)这里MainActivity.jav ...

  9. Android(java)学习笔记228:服务(service)之绑定服务调用服务里面的方法

    1.绑定服务调用服务里面的方法,图解: 步骤: (1)在Activity代码里面绑定 bindService(),以bind的方式开启服务 :                     bindServ ...

随机推荐

  1. 2020年12月-第02阶段-前端基础-CSS Day05

    CSS Day05 1. 学成在线页面制作 理解 能够说写单页面我们基本的流程 能说出常见的css初始化语句 能说出我们CSS属性书写顺序 应用 能利用ps切图 能引入外部样式表 能把psd文件转换为 ...

  2. C++图论算法——图的储存方式

    使用二维数组邻接矩阵储存图 无向图: 图G 定义图G[101][101],G[i][j]的值表示从结点vi到vj是否有边或弧,若有,取值为1或权值,若无,则取值为0或∞.以下是图G用邻接矩阵表示的列表 ...

  3. 七种方案!探讨Redis分布式锁的正确使用姿势

    前言 日常开发中,秒杀下单.抢红包等等业务场景,都需要用到分布式锁.而Redis非常适合作为分布式锁使用.本文将分七个方案展开,跟大家探讨Redis分布式锁的正确使用方式.如果有不正确的地方,欢迎大家 ...

  4. 树莓派 3/4 安装 FreeBSD

    已盼春来归 已盼春来归 今日去 愿为春来归 盼归春天来了 FreeBSD 的春天在哪里? 树莓派是什么,相信凡是关注了我们的人都不会不知道,但是介于非专业人员需要在此做简要介绍.我们的安卓手机,大部分 ...

  5. vue-cli脚手架安装及注意事项

    1.下载nodejs 链接:https://nodejs.org/en/直接下载电脑对应的版本即可. 13.5网上说不大稳定(一个表示①推荐用户版本,②最新版本) 2.安装nodejs 建议在D或者E ...

  6. CSS盒子的尺寸

    1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="U ...

  7. 第11 章 : 可观测性:你的应用健康吗?(liveness和readiness)

    课时 11:可观测性:你的应用健康吗?(莫源) 本次课程的分享主要围绕以下五个部分: 介绍一些整体需求的来源: 介绍在 K8s 中 Liveness 和 Readiness 的使用方式: 介绍在 K8 ...

  8. 【近取 key】NABCD分析

    项目 内容 这个作业属于哪个课程 2021春季计算机学院软件工程(罗杰 任健) 这个作业的要求在哪里 团队项目-NABCD分析 我在这个课程的目标是 提升工程能力和团队意识,熟悉软件开发的流程 这个作 ...

  9. Kafka核心技术与实战,分布式的高性能消息引擎服务

    Kafka是LinkedIn开发并开源的一套分布式的高性能消息引擎服务,是大数据时代数据管道技术的首选. 如今的Kafka集消息系统.存储系统和流式处理平台于一身,并作为连接着各种业务前台和数据后台的 ...

  10. Leedcode算法专题训练(分治法)

    归并排序就是一个用分治法的经典例子,这里我用它来举例描述一下上面的步骤: 1.归并排序首先把原问题拆分成2个规模更小的子问题. 2.递归地求解子问题,当子问题规模足够小时,可以一下子解决它.在这个例子 ...