转载:http://blog.csdn.net/zdy0_2004/article/details/40461571

#define _WIN32_WINNT 0x502
#define _CRT_SECURE_NO_WARNINGS
#include <Windows.h>
#include <Shlwapi.h>
#include <WtsApi32.h>
#include <UserEnv.h>
#include <iostream>
#include <fstream>
#include <atlbase.h> static const char* const lpServiceName = "ProtectService";
static SERVICE_STATUS_HANDLE hServiceStatus = NULL;
static SERVICE_STATUS ServiceStatus = {};
static char szCurDir[MAX_PATH+] = {};
static bool bRun = false;
static HANDLE hProcess = NULL;
static FILE* fLog = NULL;
static std::ofstream ofs_log; bool InstallService();
VOID WINAPI ServiceMain(DWORD dwArgc,LPTSTR *lpszArgv);
VOID WINAPI HandlerFunc(DWORD dwControl);
HANDLE RunAsLoggedUser(const char* lpPath,char* lpCmdLine);
void WorkFunc(); int main(int argc, char **argv)
{
GetModuleFileName(NULL,szCurDir,MAX_PATH);
*strrchr(szCurDir,'\\') = '\0'; char szLogPath[MAX_PATH+];
sprintf(szLogPath,"%s\\Service.log",szCurDir);
fLog = fopen(szLogPath,"a+");
setvbuf(fLog,NULL,_IONBF,); ofs_log.open(szLogPath,std::ios::app); SERVICE_TABLE_ENTRY ServiceTable[];
char szBuffer[];
strcpy(szBuffer,lpServiceName);
ServiceTable[].lpServiceName = szBuffer;
ServiceTable[].lpServiceProc = (LPSERVICE_MAIN_FUNCTION)ServiceMain; ServiceTable[].lpServiceName = NULL;
ServiceTable[].lpServiceProc = NULL; // 启动服务的控制分派机线程
if (!StartServiceCtrlDispatcher(ServiceTable))
{
ofs_log<<"程序不是以服务方式启动"<<std::endl;
std::cout<<"程序不是以服务方式启动,要创建服务并启动吗?y/n:";
if (getchar() == 'y')
{
// 安装服务
if (!InstallService())
{
ofs_log<<"安装服务失败"<<std::endl;
std::cout<<"安装服务失败,具体原因请查看日志"<<std::endl;
return ;
}
ofs_log<<"安装服务成功"<<std::endl;
} }
return ;
} bool InstallService()
{
SC_HANDLE hSCManager = OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS);
if (!hSCManager)
{
ofs_log<<"OpenSCManager失败,错误码为:"<<GetLastError()<<std::endl;
return false;
} SC_HANDLE hService = OpenService(hSCManager,lpServiceName,SERVICE_QUERY_CONFIG);
if (hService)
{
ofs_log<<"服务已经存在"<<std::endl;
CloseServiceHandle(hSCManager);
CloseServiceHandle(hService);
return false;
} char szPath[MAX_PATH+];
GetModuleFileName(NULL,szPath,MAX_PATH);
hService = CreateService(hSCManager,
lpServiceName,
lpServiceName,
SERVICE_ALL_ACCESS,
SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS,
SERVICE_AUTO_START,
SERVICE_ERROR_NORMAL,
szPath,
NULL,
NULL,
NULL,
NULL,
NULL);
if (!hService)
{
ofs_log<<"CreateService失败,错误码为"<<GetLastError()<<std::endl;
CloseServiceHandle(hSCManager);
return false;
} if (!StartService(hService,,NULL))
{
ofs_log<<"服务安装成功,但是启动服务失败,错误码为:"<<GetLastError()<<std::endl;
CloseServiceHandle(hService);
CloseServiceHandle(hSCManager);
return false;
} CloseServiceHandle(hService);
CloseServiceHandle(hSCManager); return true;
} VOID WINAPI ServiceMain( DWORD dwArgc,LPTSTR *lpszArgv )
{
ServiceStatus.dwServiceType = SERVICE_WIN32;
ServiceStatus.dwCurrentState = SERVICE_RUNNING;
ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_SHUTDOWN | SERVICE_ACCEPT_STOP;
hServiceStatus = RegisterServiceCtrlHandler(lpServiceName,HandlerFunc);
if (!hServiceStatus)
{
ofs_log<<"RegisterServiceCtrlHandler失败,错误码为:"<<GetLastError()<<std::endl;
return;
}
if (!SetServiceStatus(hServiceStatus,&ServiceStatus))
{
ofs_log<<"SetServiceStatus失败,错误码为:"<<GetLastError()<<std::endl;
return;
} bRun = true;
WorkFunc();
} VOID WINAPI HandlerFunc( DWORD dwControl )
{
ofs_log<<"收到服务消息:"<<dwControl<<std::endl; if (dwControl == SERVICE_CONTROL_STOP || dwControl == SERVICE_CONTROL_SHUTDOWN)
{
// 停止服务
ofs_log<<"服务停止"<<std::endl;
ServiceStatus.dwCurrentState = SERVICE_STOPPED;
bRun = false;
if (hProcess)
{
TerminateProcess(hProcess,);
}
} SetServiceStatus(hServiceStatus,&ServiceStatus);
} HANDLE RunAsCreator(const char* lpPath, char* lpCmdLine)
{
if (!PathFileExists(lpPath))
{
ofs_log<<"指定的要启动的程序不存在"<<std::endl;
return NULL;
} char szSubProcCurDir[MAX_PATH];
strcpy(szSubProcCurDir,lpPath);
*strrchr(szSubProcCurDir,'\\') = '\0'; STARTUPINFO si = {};
PROCESS_INFORMATION pi = {};
si.cb = sizeof(si); if (!CreateProcess(lpPath,lpCmdLine,NULL,NULL,FALSE,NORMAL_PRIORITY_CLASS | CREATE_NEW_CONSOLE,NULL,szSubProcCurDir,&si,&pi))
{
ofs_log<<"CreateProcess失败,错误码为:"<<GetLastError()<<std::endl;
return NULL;
} if (pi.hThread && pi.hThread != INVALID_HANDLE_VALUE)
{
CloseHandle(pi.hThread);
} return pi.hProcess;
} HANDLE RunAsLoggedUser( const char* lpPath,char* lpCmdLine )
{
if (!PathFileExists(lpPath))
{
ofs_log<<"指定的要启动的程序不存在"<<std::endl;
return NULL;
} DWORD dwSid = WTSGetActiveConsoleSessionId();
ofs_log<<"当前登录用户ID为:"<<dwSid<<std::endl; HANDLE hExistingToken = NULL;
if (!WTSQueryUserToken(dwSid,&hExistingToken))
{
ofs_log<<"WTSQueryUserToken失败,错误码为:"<<GetLastError()<<std::endl;
return NULL;
} HANDLE hNewToken = NULL;
if (!DuplicateTokenEx(hExistingToken,MAXIMUM_ALLOWED,NULL,SecurityIdentification,TokenPrimary,&hNewToken))
{
ofs_log<<"DuplicateTokenEx失败,错误码为:"<<GetLastError()<<std::endl;
CloseHandle(hExistingToken);
return NULL;
}
CloseHandle(hExistingToken); LPVOID pEnv = NULL;
DWORD dwCreationFlags = NORMAL_PRIORITY_CLASS | CREATE_NEW_CONSOLE;
if (CreateEnvironmentBlock(&pEnv,hNewToken,FALSE))
{
dwCreationFlags |= CREATE_UNICODE_ENVIRONMENT;
} STARTUPINFO si = {};
PROCESS_INFORMATION pi = {};
si.cb = sizeof(si);
si.lpDesktop = "WinSta0\\Default"; char szSubProcCurDir[MAX_PATH+];
strcpy(szSubProcCurDir,lpPath);
*strrchr(szSubProcCurDir,'\\') = '\0'; if (!CreateProcessAsUser(hNewToken,lpPath,lpCmdLine,NULL,NULL,FALSE,dwCreationFlags,pEnv,szSubProcCurDir,&si,&pi))
{
ofs_log<<"CreateProcessAsUser失败,错误码为:"<<GetLastError()<<std::endl;
if (pEnv)
{
DestroyEnvironmentBlock(pEnv);
}
return NULL;
} if (pi.hThread && pi.hThread != INVALID_HANDLE_VALUE)
{
CloseHandle(pi.hThread);
} if (pEnv)
{
DestroyEnvironmentBlock(pEnv);
} return pi.hProcess;
} HANDLE RunAsSpecifiedUser(const char* lpUserName,const char* lpPassword,const char* lpPath,char* lpCmdLine)
{
if (!PathFileExists(lpPath))
{
ofs_log<<"指定的要启动的程序不存在"<<std::endl;
return NULL;
} HANDLE hExistingToken = NULL;
if (!LogonUser(lpUserName,NULL,lpPassword,LOGON32_LOGON_INTERACTIVE,LOGON32_PROVIDER_DEFAULT,&hExistingToken))
{
ofs_log<<"LogonUser失败,错误码为:"<<GetLastError()<<std::endl;
return NULL;
} HANDLE hNewToken = NULL;
if (!DuplicateTokenEx(hExistingToken,MAXIMUM_ALLOWED,NULL,SecurityIdentification,TokenPrimary,&hNewToken))
{
ofs_log<<"DuplicateTokenEx失败,错误码为:"<<GetLastError()<<std::endl;
CloseHandle(hExistingToken);
return NULL;
}
CloseHandle(hExistingToken); LPVOID pEnv = NULL;
DWORD dwCreationFlags = NORMAL_PRIORITY_CLASS | CREATE_NEW_CONSOLE;
if (CreateEnvironmentBlock(&pEnv,hNewToken,FALSE))
{
dwCreationFlags |= CREATE_UNICODE_ENVIRONMENT;
} STARTUPINFO si = {};
PROCESS_INFORMATION pi = {};
si.cb = sizeof(si);
//si.lpDesktop = "WinSta0\\Default"; char szSubProcCurDir[MAX_PATH+];
strcpy(szSubProcCurDir,lpPath);
*strrchr(szSubProcCurDir,'\\') = '\0'; if (!CreateProcessAsUser(hNewToken,lpPath,lpCmdLine,NULL,NULL,FALSE,dwCreationFlags,pEnv,szSubProcCurDir,&si,&pi))
{
ofs_log<<"CreateProcessAsUser失败,错误码为:"<<GetLastError()<<std::endl;
if (pEnv)
{
DestroyEnvironmentBlock(pEnv);
}
return NULL;
} if (pi.hThread && pi.hThread != INVALID_HANDLE_VALUE)
{
CloseHandle(pi.hThread);
} if (pEnv)
{
DestroyEnvironmentBlock(pEnv);
} return pi.hProcess;
} void WorkFunc()
{
char szIniPath[MAX_PATH+];
sprintf(szIniPath,"%s\\config.ini",szCurDir);
if (!PathFileExists(szCurDir))
{
ofs_log<<"配置文件不存在"<<std::endl;
} char szProgPath[MAX_PATH+];
GetPrivateProfileString("PROGRAM","PATH","",szProgPath,MAX_PATH,szIniPath);
char szCmdLine[];
GetPrivateProfileString("PROGRAM","CMD","",szCmdLine,,szIniPath);
int method = GetPrivateProfileInt("USERINFO","METHOD",,szIniPath);
char szUserName[];
char szPassword[];
GetPrivateProfileString("USERINFO","UID","",szUserName,,szIniPath);
GetPrivateProfileString("USERINFO","PWD","",szPassword,,szIniPath); while (bRun)
{
switch (method)
{
case :
hProcess = RunAsCreator(szProgPath,szCmdLine);
break;
case :
hProcess = RunAsLoggedUser(szProgPath,szCmdLine);
break;
case :
hProcess = RunAsSpecifiedUser(szUserName,szPassword,szProgPath,szCmdLine);
break;
default:
ofs_log<<"未知的启动方式:"<<method<<std::endl;
return;
} if (!hProcess)
{
ofs_log<<"创建进程失败失败"<<std::endl;
}
WaitForSingleObject(hProcess,INFINITE);
CloseHandle(hProcess);
hProcess = NULL;
ofs_log<<"被守护进程退出"<<std::endl;
Sleep();
}
}

守护进程Demo

VC++使用服务做守护进程的示例(转载)的更多相关文章

  1. Supervisor 为服务创建守护进程

    今天需要再服务上部署一个.net 方面的项目:当时开启服务的命令只能在前台执行:使用nohub CMD &等放在后台开启服务都会宕机:所以搜寻了Supervisor 这个解决办法,为服务创建守 ...

  2. Linux控制服务和守护进程

    目录 控制服务和守护进程 1.systemd 1.1.systemd简介 1.2.systemd的新特性 1.3.systemd的核心概念Unit 2.使用systemctl管理服务 控制服务和守护进 ...

  3. Linux_控制服务与守护进程

    一.systemd 1.systemd简介 1️⃣:systemd是用户空间的第一个应用程序,即/sbin/init 2️⃣:init程序的类型: SysV风格:init(centos5),实现系统初 ...

  4. Windows守护进程简单示例

    转载: https://blog.csdn.net/kikaylee/article/details/51395360 /* @描述:一个简单的Windows守护进程的例子(C++版本) @作者:ki ...

  5. PHP实现多进程并行操作,可做守护进程(转,备用)

    <?php /** * 入口函数 * 将此文件保存为 ProcessOpera.php * 在terminal中运行 /usr/local/php/bin/php ProcessOpera.ph ...

  6. java实现服务端守护进程来监听客户端通过上传json文件写数据到hbase中

    1.项目介绍: 由于大数据部门涉及到其他部门将数据传到数据中心,大部分公司采用的方式是用json文件的方式传输,因此就需要编写服务端和客户端的小程序了.而我主要实现服务端的代码,也有相应的客户端的测试 ...

  7. linux分享一:进程全攻略--守护进程(服务)

    概括: 进程是程序的运行实例.进程对应一个唯一的进程PID, 统一程序的多个实例可以同时运行,他们的pid互不相同. 进程一般分为交互进程.批处理进程和守护进程(daemons)三类 一:什么是守护进 ...

  8. 深入理解Linux操作系统守护进程的意义

    Linux服务器在启动时需要启动很多系统服务,它们向本地和网络用户提供了Linux的系统功能接口,直接面向应用程序和用户.提供这些服务的程序是由运行在后台的守护进程(daemons)来执行的.守护进程 ...

  9. 守护进程与Supervisor

    博客链接:http://www.cnblogs.com/zhenghongxin/p/8676565.html 消息队列处理后台任务带来的问题 在系统稍微大些的时候,我们经常会用到消息队列(实现的方式 ...

随机推荐

  1. Chrome浏览器扩展 获取用户密码

    Chrome 浏览器允许安装第三方扩展程序以扩展浏览器并给浏览器加入新的功能,扩展使用 JavaScript 以及 HTMl 编写并允许互相访问和控制 DOM. 因为允许访问 DOM,攻击者就可以读取 ...

  2. SecureFX 中文乱码

      1. 找到SecureFX配置文件夹(选项–全局选项,常规下的配置文件夹),比如:C:\Users\James\AppData\Roaming\VanDyke\Config\Sessions 2. ...

  3. Java Native Interface 基于JNI的嵌入式手机软件开发实例

    1.通过JNI和c/c++的库组件.其他代码交互 2.java和c不能互通的原因时数据类型问题 Introduction https://docs.oracle.com/javase/8/docs/t ...

  4. 杭电oj题目分类

    基础题:1000.1001.1004.1005.1008.1012.1013.1014.1017.1019.1021.1028.1029.1032.1037.1040.1048.1056.1058.1 ...

  5. PAT Spell It Right [非常简单]

    1005 Spell It Right (20)(20 分) Given a non-negative integer N, your task is to compute the sum of al ...

  6. AspxGridView点滴

    1:页码设置 1>: <SettingsPager Summary-Text="当前第 {0} 页 总共 {1} 页 ({2} 条记录)"></Settin ...

  7. 谁有stanford ner训练语料

    [冒泡]良橙(1759086270) 12:14:17请教大家一个问题,我有1w多句用户的问题,但是有些包含了一些骂人,数字,特殊符号,甚至,语句不通,有什么方法可以过滤不[吐槽]爱发呆的小狮子(19 ...

  8. js五星好评2

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  9. VS2010/MFC编程入门之五十一(图形图像:GDI对象之画刷CBrush)

    上一节中鸡啄米主要讲的是画笔CPen的用法,前面也说了,GDI对象中最常用的就是画笔和画刷,本节就讲讲画刷CBrush. 鸡啄米依然是通过实例的方式来说明画刷的用法.此实例要实现的功能是,对话框上有一 ...

  10. 公司里面用的iTextSharp(教程)---生成一个简答的PDF的语法

    本来打算先写一个项目大家一起练习的,但是后来发现不懂一些基本的语法,几乎做了之后也有些不明白,下面我们一起简简单单的看一下哈~~ 语法1:Document document = new Documen ...