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

最新文章

  1. ACM/ICPC 之 DFS+SPFA-贪心+最短路(POJ2679)
  2. pyqt5 开发环境
  3. BZOJ3787 : Gty的文艺妹子序列
  4. 转: svn合并分支到trunk
  5. in和exists的区别与SQL执行效率
  6. 九度OJ 1410 垒积木 -- 动态规划
  7. linux强大IDE——Geany配置说明
  8. UNDO表空间损坏,爆满,ORA-600[4194]/[4193]错误解决
  9. android中控件公用产生的冲突的解决办法
  10. 1.Getting Started
  11. JavaScript复习
  12. Spring Security Session并发控制原理解析
  13. P和C
  14. Linux RPM、YUM、APT包管理工具
  15. PHPMailer 使用方法(支持群发):
  16. RabbitMQ上手记录–part 2 - 安装RabbitMQ
  17. Vue 框架-01- 入门篇 图文教程
  18. JS高级 2
  19. LOJ #3049. 「十二省联考 2019」字符串问题
  20. iOS 崩溃日志分析(个人总结,最实用)

热门文章

  1. MyBatis中的Map
  2. C#中委托、匿名函数、Lambda表达式的一些个人理解
  3. rest framework Views
  4. jwt以及如何使用jwt实现登录
  5. 冗余网络构建方案对比:VRRP协议、多网卡绑定及WN202冗余链路网卡
  6. matplotlib常规使用方法
  7. Android学习之异步消息处理机制
  8. Python3 使用requests请求,解码时出错:&#39;utf8&#39; codec can&#39;t decode byte 0x83 in position 1: invalid start byte
  9. 日志文件删除shell脚本
  10. 开源一周岁,MindSpore新特性巨量来袭