描述
前期知识
- windows服务控制
- windows服务由三部分组成:服务应用程序、服务控制程序(SCP)和服务控制管理器(SCM),SCM维护服务状态,通过SCP的ControlService函数对服务程序进行控制
- 链接
- windows字符串处理
- Windows中有一个Shlwapi.dll文件,包含了大量的Windows字符串处理方法
- 第一类是字符串处理函数,通常以Str开头,第二类是路径或者文件夹处理函数,通常以Path开头,第三类是注册表处理函数,通常以SH开头
- 静态库、动态库和导入库的使用
代码
外壳
#include "stdafx.h"
#include "ServiceOperate.h"
int _tmain(int argc, _TCHAR* argv[])
{
BOOL bRet = FALSE;
char szExePath[] = "E:\\Project\\Cpp\\BlackHat\\CreateServiceAsUser\\x64\\Release\\CreateServiceAsUser.exe";
bRet = SystemServiceOperate(szExePath, 0);
if (bRet)
{
printf("INSTALL OK.\n");
}
else
{
printf("INSTALL ERROR.\n");
}
bRet = SystemServiceOperate(szExePath, 1);
if (bRet)
{
printf("START OK.\n");
}
else
{
printf("START ERROR.\n");
}
system("pause");
bRet = SystemServiceOperate(szExePath, 2);
if (bRet)
{
printf("STOP OK.\n");
}
else
{
printf("STOP ERROR.\n");
}
bRet = SystemServiceOperate(szExePath, 3);
if (bRet)
{
printf("UNINSTALL OK.\n");
}
else
{
printf("UNINSTALL ERROR.\n");
}
return 0;
}
函数的实现
- 首先打开SCM管理器
- 通过SCM管理器调用CreateService、StartService、ControlService等函数,创建服务并控制服务状态
#include "stdafx.h"
#include "ServiceOperate.h"
void ShowError(char* lpszText)
{
char szErr[MAX_PATH] = { 0 };
wsprintf(szErr, "%s Error!\nError Code Is: ", lpszText, ::GetLastError());
::MessageBox(NULL, szErr, "ERROR", MB_OK | MB_ICONERROR);
}
BOOL SystemServiceOperate(char* Path, int Op)
{
BOOL bRet = TRUE;
char szName[MAX_PATH] = { 0 };
::lstrcpy(szName, Path);
::PathStripPath(szName);
SC_HANDLE shOSCM = NULL, shCS = NULL;
SERVICE_STATUS ss;
DWORD dwErrorCode = 0;
BOOL bSuccess = FALSE;
shOSCM = ::OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
if (!shOSCM)
{
ShowError("OpenSCManager");
return FALSE;
}
if (0 != Op)
{
shCS = OpenService(shOSCM, szName, SERVICE_ALL_ACCESS);
if (!shCS)
{
ShowError("OpenService");
::CloseServiceHandle(shOSCM);
shOSCM = NULL;
return FALSE;
}
}
switch (Op)
{
case 0:
{
shCS = ::CreateService(shOSCM, szName, szName,
SERVICE_ALL_ACCESS,
SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS,
SERVICE_AUTO_START,
SERVICE_ERROR_NORMAL,
Path, NULL, NULL, NULL, NULL, NULL);
if (!shCS)
{
ShowError("CreateService");
bRet = FALSE;
}
break;
}
case 1:
{
if (!::StartService(shCS, 0, NULL))
{
ShowError("StartService");
bRet = FALSE;
}
break;
}
case 2:
{
if (!::ControlService(shCS, SERVICE_CONTROL_STOP, &ss))
{
ShowError("ControlService");
bRet = FALSE;
}
break;
}
case 3:
{
if (!::DeleteService(shCS))
{
ShowError("DeleteService");
bRet = FALSE;
}
}
default:
break;
}
if (shCS)
{
::CloseServiceHandle(shCS);
shCS = NULL;
}
if (shOSCM)
{
::CloseServiceHandle(shOSCM);
shOSCM = NULL;
}
return bRet;
}
遇到的问题
- "const char *“ 类型的实参与 “char *” 类型的形参不兼容"
- 在VS2019中依次点击项目->属性->C/C+±>语言->符合模式,将原来的“是”改为“否”即可
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库