win32 - service的创建
参考这篇教程:Simple Windows Service in C++
安装service需要在管理员权限下运行cmd,并输入下面的命令行
C:\>sc create "My Sample Service" binPath= C:\SampleService.exe
My Sample Service是service name,可以随意更改。 后面的exe程序是我们需要执行的service,代码如下。
卸载service,输入,
C:\>sc delete "My Sample Service"
代码样例:
#include <Windows.h>
#include <tchar.h>
#include <wtsapi32.h> #pragma comment(lib,"Wtsapi32.lib") SERVICE_STATUS g_ServiceStatus = { 0 };
SERVICE_STATUS_HANDLE g_StatusHandle = NULL;
HANDLE g_ServiceStopEvent = INVALID_HANDLE_VALUE; HANDLE g_hChildStd_Rd = NULL;
HANDLE g_hChildStd_Wr = NULL; VOID WINAPI ServiceMain(DWORD argc, LPTSTR* argv);
VOID WINAPI ServiceCtrlHandler(DWORD);
DWORD WINAPI ServiceWorkerThread(LPVOID lpParam); #define SERVICE_NAME _T("My Sample Service") int _tmain(int argc, TCHAR* argv[])
{
OutputDebugString(_T("My Sample Service: Main: Entry")); SERVICE_TABLE_ENTRY ServiceTable[] =
{
{(LPWSTR)SERVICE_NAME, (LPSERVICE_MAIN_FUNCTION)ServiceMain},
{NULL, NULL}
}; if (StartServiceCtrlDispatcher(ServiceTable) == FALSE)
{
OutputDebugString(_T("My Sample Service: Main: StartServiceCtrlDispatcher returned error"));
return GetLastError();
} OutputDebugString(_T("My Sample Service: Main: Exit"));
return 0;
} VOID WINAPI ServiceMain(DWORD argc, LPTSTR* argv)
{
HANDLE hThread;
DWORD Status = E_FAIL; OutputDebugString(_T("My Sample Service: ServiceMain: Entry")); g_StatusHandle = RegisterServiceCtrlHandler(SERVICE_NAME, ServiceCtrlHandler); if (g_StatusHandle == NULL)
{
OutputDebugString(_T("My Sample Service: ServiceMain: RegisterServiceCtrlHandler returned error"));
goto EXIT;
} // Tell the service controller we are starting
ZeroMemory(&g_ServiceStatus, sizeof(g_ServiceStatus));
g_ServiceStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
g_ServiceStatus.dwControlsAccepted = 0;
g_ServiceStatus.dwCurrentState = SERVICE_START_PENDING;
g_ServiceStatus.dwWin32ExitCode = 0;
g_ServiceStatus.dwServiceSpecificExitCode = 0;
g_ServiceStatus.dwCheckPoint = 0; if (SetServiceStatus(g_StatusHandle, &g_ServiceStatus) == FALSE)
{
OutputDebugString(_T("My Sample Service: ServiceMain: SetServiceStatus returned error"));
} /*
* Perform tasks neccesary to start the service here
*/
OutputDebugString(_T("My Sample Service: ServiceMain: Performing Service Start Operations")); // Create stop event to wait on later.
g_ServiceStopEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
if (g_ServiceStopEvent == NULL)
{
OutputDebugString(_T("My Sample Service: ServiceMain: CreateEvent(g_ServiceStopEvent) returned error")); g_ServiceStatus.dwControlsAccepted = 0;
g_ServiceStatus.dwCurrentState = SERVICE_STOPPED;
g_ServiceStatus.dwWin32ExitCode = GetLastError();
g_ServiceStatus.dwCheckPoint = 1; if (SetServiceStatus(g_StatusHandle, &g_ServiceStatus) == FALSE)
{
OutputDebugString(_T("My Sample Service: ServiceMain: SetServiceStatus returned error"));
}
goto EXIT;
} // Tell the service controller we are started
g_ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP;
g_ServiceStatus.dwCurrentState = SERVICE_RUNNING;
g_ServiceStatus.dwWin32ExitCode = 0;
g_ServiceStatus.dwCheckPoint = 0; if (SetServiceStatus(g_StatusHandle, &g_ServiceStatus) == FALSE)
{
OutputDebugString(_T("My Sample Service: ServiceMain: SetServiceStatus returned error"));
} // Start the thread that will perform the main task of the service
hThread = CreateThread(NULL, 0, ServiceWorkerThread, NULL, 0, NULL); OutputDebugString(_T("My Sample Service: ServiceMain: Waiting for Worker Thread to complete")); // Wait until our worker thread exits effectively signaling that the service needs to stop
WaitForSingleObject(hThread, INFINITE); OutputDebugString(_T("My Sample Service: ServiceMain: Worker Thread Stop Event signaled")); /*
* Perform any cleanup tasks
*/
OutputDebugString(_T("My Sample Service: ServiceMain: Performing Cleanup Operations")); CloseHandle(g_ServiceStopEvent); g_ServiceStatus.dwControlsAccepted = 0;
g_ServiceStatus.dwCurrentState = SERVICE_STOPPED;
g_ServiceStatus.dwWin32ExitCode = 0;
g_ServiceStatus.dwCheckPoint = 3; if (SetServiceStatus(g_StatusHandle, &g_ServiceStatus) == FALSE)
{
OutputDebugString(_T("My Sample Service: ServiceMain: SetServiceStatus returned error"));
} EXIT:
OutputDebugString(_T("My Sample Service: ServiceMain: Exit")); return;
} VOID WINAPI ServiceCtrlHandler(DWORD CtrlCode)
{
OutputDebugString(_T("My Sample Service: ServiceCtrlHandler: Entry")); switch (CtrlCode)
{
case SERVICE_CONTROL_STOP: OutputDebugString(_T("My Sample Service: ServiceCtrlHandler: SERVICE_CONTROL_STOP Request")); if (g_ServiceStatus.dwCurrentState != SERVICE_RUNNING)
break; /*
* Perform tasks neccesary to stop the service here
*/ g_ServiceStatus.dwControlsAccepted = 0;
g_ServiceStatus.dwCurrentState = SERVICE_STOP_PENDING;
g_ServiceStatus.dwWin32ExitCode = 0;
g_ServiceStatus.dwCheckPoint = 4; if (SetServiceStatus(g_StatusHandle, &g_ServiceStatus) == FALSE)
{
OutputDebugString(_T("My Sample Service: ServiceCtrlHandler: SetServiceStatus returned error"));
} // This will signal the worker thread to start shutting down
SetEvent(g_ServiceStopEvent); break; default:
break;
} OutputDebugString(_T("My Sample Service: ServiceCtrlHandler: Exit"));
} DWORD WINAPI ServiceWorkerThread(LPVOID lpParam)
{
OutputDebugString(_T("My Sample Service: ServiceWorkerThread: Entry"));
WCHAR station[] = L"Winsta0\\default";
SECURITY_ATTRIBUTES saAttr;
saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
saAttr.bInheritHandle = TRUE;
saAttr.lpSecurityDescriptor = NULL; CreatePipe(&g_hChildStd_Rd, &g_hChildStd_Wr, &saAttr, 0); STARTUPINFO si;
ZeroMemory(&si, sizeof(STARTUPINFO));
si.cb = sizeof(STARTUPINFO);
si.hStdOutput = g_hChildStd_Wr;
si.hStdError = g_hChildStd_Wr;
si.lpDesktop = station;
si.dwFlags = STARTF_USESTDHANDLES;
PROCESS_INFORMATION pi; HANDLE hToken;
bool err = WTSQueryUserToken(WTSGetActiveConsoleSessionId(), &hToken);
WCHAR path[] = L"D:\\child.exe";
if (CreateProcessAsUser(hToken, path, NULL, 0, 0, true, CREATE_NO_WINDOW, 0, 0, &si, &pi))
{
CloseHandle(g_hChildStd_Wr);
DWORD ret = WaitForSingleObject(pi.hProcess, 2000); //wait for the child process exit.
if (ret == 0)
{
WCHAR chBuf[100]= L"HELLO WORLD";
DWORD dwRead, dwWritten,
err = ReadFile(g_hChildStd_Rd, chBuf, 100, &dwRead, NULL);
HANDLE hFile = CreateFile(L"123.txt", // name of the write
GENERIC_WRITE, // open for writing
0, // do not share
NULL, // default security
CREATE_NEW, // create new file only
FILE_ATTRIBUTE_NORMAL, // normal file
NULL); // no attr. template
WriteFile(
hFile, // open file handle
chBuf, // start of data to write
100, // number of bytes to write
&dwWritten, // number of bytes that were written
NULL); // no overlapped structure
}
}
// Periodically check if the service has been requested to stop
while (WaitForSingleObject(g_ServiceStopEvent, 0) != WAIT_OBJECT_0)
{
/*
* Perform main service function here
*/ // Simulate some work by sleeping
Sleep(3000);
} OutputDebugString(_T("My Sample Service: ServiceWorkerThread: Exit")); return ERROR_SUCCESS;
}
在Winsta0\default中创建子进程,在service中使用CreateProcessAsUser调用子进程。
文档参考:Window Stations
如果需要service与子进程建立通信,可以使用匿名管道,代码中已经创建了管道,我没有使用它们。
如果对匿名管道的数据传输有兴趣的,可以参考我的另外一篇文章: win32 - 匿名管道的使用
win32 - service的创建的更多相关文章
- Web Service 的创建简单编码、发布和部署
最近,老大准备将已有的C/S架构项目中的通信部分做成通用,需要将其支持WebService为以后项目向着B/S架构升级做好铺垫,为此身为屌丝的我去各种百度WebService是个什么卵玩意,然后逐渐搭 ...
- 在Salesforce中向外公布Service去创建Lead,并且用Asp.Net去调用此Service
1):在Salesforce中如何配置,向外公布此Service,请看如下链接: http://www.shellblack.com/marketing/web-to-lead/ 2):如何在Asp. ...
- Win32 SDK程序创建一些控件(简单调用InitCommonControlsEx,并指定ICC_LISTVIEW_CLASSES控件就可以了)
在Win32 SDK中创建一些控件的时候需要注意一下(具体是哪些控件请参看MSDN文档中列出来的) /* MSDN:Carries information used to load common co ...
- Win32 多线程的创建方法和基本使用
Win32多线程的创建方法主要有: (1)CreateThread() (2)_beginthread()&&_beginthreadex() (3)AfxBeginThread() ...
- SQL Server Service Broker创建单个数据库会话
概述 SQL Server Service Broker 用来创建用于交换消息的会话.消息在目标和发起方这两个端点之间进行交换.消息用于传输数据和触发消息收到时的处理过程.目标和发起方既可以在同一数据 ...
- SQL Server Service Broker创建单个数据库会话(消息队列)
概述 SQL Server Service Broker 用来创建用于交换消息的会话.消息在目标和发起方这两个端点之间进行交换.消息用于传输数据和触发消息收到时的处理过程.目标和发起方既可以在同一数据 ...
- Android的Service的创建与使用
Service介绍 Service是Android四大组件中与Activity最为相似的组件,它们都代表可执行的程序,区别是:Service一直在后台运行,没有用户界面.使用service要向Acti ...
- Docker Kubernetes Service 代理服务创建
Docker Kubernetes Service 代理服务创建 创建Service需要提前创建好pod容器.再创建Service时需要指定Pod标签,它会提供一个暴露端口默会分配容器内网访问的唯一 ...
- C# window service的创建
其实我也是第一次在博客园写博客,看到那些高手说自己要多动手写博客,于是乎自己也尝试尝试. 废话不多说.这几天在研究window service,通过查找各种大神写的博客,我终于成功的自己写出来了. 下 ...
- 从微信推送看Android Service的创建和销毁
启动服务是有两组参数影响服务的状态. 1.在onStartCommand(Intent intent, int flags, int startId) 接口中返回值,例如 START_STICKY; ...
随机推荐
- [转帖]1. awk基础,awk介绍,awk基本语法,直接使用action,打印列,初识列和行,\$0、\$NF、NF,基础示例,begin模式,end模式
文章目录 前言 awk介绍 awk基本语法 直接使用action 打印列 初识列和行 \$0.\$NF.NF 基础示例 初识模式(begin end) 总结 友情链接 前言 本小节是awk基础入门课程 ...
- [转帖]minio性能测试
https://zhangzhuo.ltd/articles/2021/09/08/1631106274550.html 压测参数说明 压测数据量为:2个backet,每个backet为10000对象 ...
- [转帖]【JVM】堆内存与栈内存详解
堆和栈的定义 java把内存分成栈内存和堆内存. (1)栈内存 在函数中定义的一些基本类型的变量和对象的引用变量都是在函数的栈内存中分配. 当在一段代码块中定义一个变量时,java就在栈中为这个变量分 ...
- [转帖]记录自己安装内存带宽测试工具——Stream过程
测试环境: CPU:Kunpeng 920 8Core MEM:16G Storage:200G OS:openEuler 20.03 (LTS-SP3) 1 服务器资源监控工具--Stream 1. ...
- SHA加密在实际应用中的优势与局限
SHA加密算法简介 SHA(Secure Hash Algorithm)加密算法是一种单向加密算法,常用于加密数据的完整性校验和加密签名.它是由美国国家安全局(NSA)设计并广泛应用于各种安全场景.S ...
- 热更新适配ibatis原理浅析
一.热更新解决了什么问题? 在研发过程中,每个研发同学在联调.自测阶段中总会频繁的去执行编译.构建.打包的动作,遇到比较大的项目,执行一套流程下来,往往需要3-10分钟左右,极大的降低了研发的速度,基 ...
- 机器学习从入门到放弃:卷积神经网络CNN(一)
一.前言 在上一篇中我们使用全连接网络,来构建我们的手写数字图片识别应用,取得了很好的效果.但是值得注意的是,在实验的最后,最后我们无论把 LOSS 优化到如何低,似乎都无法在测试数据集 test d ...
- node+express+ multer 实现文件上传入门
文件上传 文件上传需要借助一个中间件 multer 因此我们需要安装 cnpm install multer --save 前端界面 在express创建的项目下的 public/upload目录下创 ...
- 关于Js debounce(防抖)函数和throttle(节流)小结
闭包的实际运用防抖 防抖:当持续触发事件时,一定时间段内没有再触发事件,事件处理函数才会执行一次, 如果设定的时间到来之前,又一次触发了事件,就重新开始 延时. (如果在一段时间内,又触发了该事件:就 ...
- 【JS 逆向百例】Ether Rock 空投接口 AES256 加密分析
关注微信公众号:K哥爬虫,持续分享爬虫进阶.JS/安卓逆向等技术干货! 声明 本文章中所有内容仅供学习交流,抓包内容.敏感网址.数据接口均已做脱敏处理,严禁用于商业用途和非法用途,否则由此产生的一切后 ...