(中行雷威2018.3.12)

(同一个世界,同一个梦想,交流学习C++Builder XE10,传承c++builder的魅力!欢迎各地朋友加入我的QQ群484979943,进群密码“BCB”,同时也请将该群号广为宣传,希望能够广集各方高手,共同进步。如需下载开发工具及源代码请加入我的QQ群)

【阅读倡议】

1、有问题请留言;

2、没问题请点赞;

3、看连载请加群;

4、下源码请加群;

【开发工具】

1、C++Builder10.2.2tokyo

-------------------------------------------------------------------------------------------------------------------------------

本文将介绍如何创建一个操作系统层面的服务程序,并同步介绍如何通过系统服务自动监控桌面程序进程,如何杀掉进程,如何启动进程。本文穿越了WIN7以后操作系统session隔离的新特性,有效解决了旧版本下好用的调用功能在新系统下调用成功但是客户看不到界面的问题。

一、新建项目

1、新建服务项目smartService

File->New->Other新建一个Service Application服务项目

将窗口文件Unit???.cpp保存为UnitMain.cpp,将项目文件保存为bocSmartService.cbproj。

打开MainForm窗口,在左侧属性设置界面里将Name属性和DisplayName属性都设置为smartService,

将Interactive属性设置为True。

2、新建线程smartThread

File-》New-》other新建线程smartThread,下图选择ThreadObject

在新建线程窗口里输入你的线程的类名称TsmartThread

将新建的线程的Unit???.cpp文件保存为UnitThread.cpp

3、设置wchar_t编码映射关系

二、代码实现

1、MainForm.cpp代码

//---------------------------------------------------------------------------

#include "UnitMain.h"
#include "UnitThread.h"

/*自定义*/

#include <Registry.hpp>//读取可执行文件同名ini配置文件的头文件声明

TsmartThread *smartThread;//定义全局smart线程变量
String openFilePath,openFileName;//定义要坚守的程序目录(c:\dir)和名称(b.exe)

//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"

TsmartService *smartService;
//---------------------------------------------------------------------------
__fastcall TsmartService::TsmartService(TComponent* Owner)
: TService(Owner)
{
}

void __stdcall ServiceController(unsigned CtrlCode)
{
smartService->Controller(CtrlCode);
}

TServiceController __fastcall TsmartService::GetServiceController(void)
{
return (TServiceController) ServiceController;
}

//FormMain添加的Pause暂停事件---------------------------------------------------------------------------
void __fastcall TsmartService::ServicePause(TService *Sender, bool &Paused)
{
//暂停
smartThread->Suspend();
Paused = true;
}
//FormMain添加的Start启动事件---------------------------------------------------------------------------
void __fastcall TsmartService::ServiceStart(TService *Sender, bool &Started)
{
//启动
smartThread = new TsmartThread(false);//新建线程
Started = true;
}
//FormMain添加的Stop停止事件---------------------------------------------------------------------------
void __fastcall TsmartService::ServiceStop(TService *Sender, bool &Stopped)
{
//结束
smartThread->Terminate();
Stopped = true;
}
//FormMain添加的Continue继续事件---------------------------------------------------------------------------
void __fastcall TsmartService::ServiceContinue(TService *Sender, bool &Continued)
{
//继续
smartThread->Resume();
Continued = true;
}
//FormMain添加的OnCreate事件---------------------------------------------------------------------------
void __fastcall TsmartService::ServiceCreate(TObject *Sender)
{
//读取出程序的同名配置文件bocSmartService.ini
TIniFile *ini;
ini = new TIniFile( ChangeFileExt( Vcl::Forms::Application->ExeName, ".INI" ) );
openFileName = ini->ReadString ( "SERVICE", "openFileName", "smartOffice.exe" );
openFilePath = ini->ReadString ( "SERVICE", "openFilePath", "c:\\smartOffice" );
delete ini;
}

//---------------------------------------------------------------------------

2、MainForm.h代码

//---------------------------------------------------------------------------

#ifndef UnitMainH
#define UnitMainH
//---------------------------------------------------------------------------
#include <SysUtils.hpp>
#include <Classes.hpp>
#include <SvcMgr.hpp>
#include <vcl.h>
//---------------------------------------------------------------------------
class TsmartService : public TService
{
__published:    // IDE-managed Components
void __fastcall ServicePause(TService *Sender, bool &Paused);
void __fastcall ServiceStart(TService *Sender, bool &Started);
void __fastcall ServiceStop(TService *Sender, bool &Stopped);
void __fastcall ServiceContinue(TService *Sender, bool &Continued);
void __fastcall ServiceCreate(TObject *Sender);
private:        // User declarations
public:         // User declarations
__fastcall TsmartService(TComponent* Owner);
TServiceController __fastcall GetServiceController(void);
friend void __stdcall ServiceController(unsigned CtrlCode);
};
//---------------------------------------------------------------------------
extern PACKAGE TsmartService *smartService;
//---------------------------------------------------------------------------

#endif

3、UnitThread.cpp代码

//---------------------------------------------------------------------------
#include <System.hpp>
#pragma hdrstop
/*进程*/
#include <tlhelp32.h>  //进程api相关
#include <Wtsapi32.h>
#include <Userenv.h>   //用户token相关

#include "UnitThread.h"

#include "UnitMain.h"//引用FormMain窗口头文件

#pragma package(smart_init)
/*自定义*/
#pragma comment(lib,"Wtsapi32.lib")
#pragma comment(lib,"Userenv.lib")
//---------------------------------------------------------------------------

//   Important: Methods and properties of objects in VCL can only be
//   used in a method called using Synchronize, for example:
//
//      Synchronize(&UpdateCaption);
//
//   where UpdateCaption could look like:
//
//      void __fastcall TsmartThread::UpdateCaption()
//      {
//        Form1->Caption = "Updated in a thread";
//      }
//---------------------------------------------------------------------------

__fastcall TsmartThread::TsmartThread(bool CreateSuspended)
: TThread(CreateSuspended)
{
}
//---------------------------------------------------------------------------
void __fastcall TsmartThread::Execute()
{
/*

功能:服务执行事件

windows服务调用windows线程,windows服务的主要功能都在线程OnExecute事件里添加具体代码实现

*/
while (!Terminated)//循环
{
if(!openFilePath.IsEmpty() && !openFileName.IsEmpty())
{
StartProgress(openFileName,openFilePath+"\\"+openFileName);//调用自定义函数启动桌面程序
}
Sleep(10000);//循环间隔时间(毫秒)
}
}
//自定义函数关闭进程,本项目未用到---------------------------------------------------------------------------
bool __fastcall TsmartThread::CloseProgress( AnsiString Progress )
{
/*
功能:查找进程并关闭进程
调用:CloseProgress("coreTeam.exe");
*/
HANDLE   hSnapshotPro;
HANDLE   hSnapshotMod;
char *cStr;
wchar_t *wStr;
size_t len;

//创建遍历进程所需要的SnapshotPro
hSnapshotPro   =   CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
if   (!hSnapshotPro)
return false;
//循环遍历进程列表中的进程
PROCESSENTRY32   ProcessEntry;
ProcessEntry.dwSize=sizeof(PROCESSENTRY32);

Process32First(hSnapshotPro,   &ProcessEntry);
int   ppid = -1;
while   (Process32Next(hSnapshotPro,   &ProcessEntry)!=0)
{
wStr=ProcessEntry.szExeFile;
len=wcslen(wStr)+1;
cStr=(char *)malloc(len*sizeof(char));
wcstombs(cStr,wStr,len);
if( strcmp(cStr , Progress.c_str() ) == 0 )
{
ppid = ProcessEntry.th32ProcessID;
}
}
HANDLE   ps = OpenProcess(1,false,ppid);
if(ps&&TerminateProcess(ps,-9))
{
//myLog("程序"+Progress+"停止成功 Stop success");
return true;
}
else
{
//myLog("程序"+Progress+"停止失败 Stop fail");
return false;
}
}
//自定义函数查找启动进程---------------------------------------------------------------------------
bool __fastcall TsmartThread::StartProgress( AnsiString Progress,AnsiString File )
{
/*
功能:判断进程是否存在,如果不存在就启动
调用:StartProgress("coreTeam.exe","C:\\coreTeam\\coreTeam.exe");
*/
bool startFlag=true;
char *cStr;
wchar_t *wStr;
size_t len;
HANDLE   hSnapshotPro;
HANDLE   hSnapshotMod;
//创建遍历进程所需要的SnapshotPro
hSnapshotPro   =   CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
if(!hSnapshotPro)
{
return false;
}
//循环遍历进程列表中的进程
PROCESSENTRY32   ProcessEntry;
ProcessEntry.dwSize=sizeof(PROCESSENTRY32);
Process32First(hSnapshotPro,   &ProcessEntry);
int   ppid = -1;
while   (Process32Next(hSnapshotPro,   &ProcessEntry)!=0)
{
wStr=ProcessEntry.szExeFile;
len=wcslen(wStr)+1;
cStr=(char *)malloc(len*sizeof(char));
wcstombs(cStr,wStr,len);
if( strcmp(cStr, Progress.c_str() ) == 0 )
{
startFlag=false;
//myLog("程序"+Progress+"正在运行");
break;
}
}
//启动进程
if(!startFlag)
return false;
/*
WINDOWS后操作系统增加了安全隔离,需要先获得token才能正常显示服务调用出来的程序,
否则程序能调用起来,但是出于被隔离的system用户下面,当前用户看不到。
*/
//获取当前活动的SessionId
DWORD dwSessionId = WTSGetActiveConsoleSessionId();
HANDLE hToken = NULL;
HANDLE hTokenDup = NULL;
LPVOID  pEnv = NULL;
STARTUPINFO si;
PROCESS_INFORMATION pi;
//获取用户Token
if (!WTSQueryUserToken(dwSessionId, &hToken))
{
CloseHandle(hToken);
return false;
}
//复制Token
if (!DuplicateTokenEx(hToken, MAXIMUM_ALLOWED, NULL, SecurityIdentification, TokenPrimary, &hTokenDup))
{
CloseHandle(hToken);
return false;
}
//获取环境信息
if (!CreateEnvironmentBlock(&pEnv, hTokenDup, FALSE))
{
CloseHandle(hToken);
CloseHandle(hTokenDup);
return false;
}
//设置启动参数信息
ZeroMemory(&si, sizeof(STARTUPINFO));
si.cb = sizeof(STARTUPINFO);
si.lpDesktop = L"winsta0\\default";
ZeroMemory(&pi, sizeof(pi));
DWORD dwCreationFlag = NORMAL_PRIORITY_CLASS | CREATE_UNICODE_ENVIRONMENT | CREATE_NEW_CONSOLE;
//以当前用户启动记事本
cStr=File.c_str();
len=strlen(cStr)+1;
wStr=(wchar_t *)malloc(len*sizeof(wchar_t));
mbstowcs(wStr,cStr,len);
if (!CreateProcessAsUser(hTokenDup, wStr, NULL, NULL, NULL, FALSE, dwCreationFlag, pEnv, NULL, &si, &pi))
{
DestroyEnvironmentBlock(pEnv);
CloseHandle(hTokenDup);
CloseHandle(hToken);
}
//等待启动的进程结束
WaitForSingleObject(pi.hProcess, INFINITE);

//清理工作
DestroyEnvironmentBlock(pEnv);
CloseHandle(hTokenDup);
CloseHandle(hToken);
return true;

}
//---------------------------------------------------------------------------

4、UnitThread.h代码

//---------------------------------------------------------------------------
#ifndef UnitThreadH
#define UnitThreadH
//---------------------------------------------------------------------------
#include <System.Classes.hpp>
//---------------------------------------------------------------------------
class TsmartThread : public TThread
{
/*自定义*/
bool __fastcall CloseProgress( AnsiString Progress );//关闭进程
bool __fastcall StartProgress( AnsiString Progress,AnsiString File );//启动进程

private:
protected:
void __fastcall Execute();
public:
__fastcall TsmartThread(bool CreateSuspended);
};
//---------------------------------------------------------------------------
#endif

extern String openFilePath,openFileName;//引用FormMain开头定义的全局变量

三、服务安装

编辑两个服务安装和卸载脚本,放到上面编译后的可执行程序bocSmartService的同级别目录里。

1、instatll.bat

bocSmartService /install

net start smartService

pause

2、uninstall.bat

net stop smartService

bocSmartService /uninstall

pause

3、编辑配置文件

配置文件名字应该为可执行程序的同名.ini文件,本项目为bocSmartService.ini文件,在配置文件里设置你要监控的程序的目录和文件名称(目录不能以“\”结尾)

[SERVICE]

openFilePath=c:\smartOffice

openFileName=smartOffice.exe

四、测试效果

右键运行上述的install.bat,服务安装后将每十秒调用启动一次你配置的被监控程序smartOffice.exe,如果程序已经启动则不动作,否则就启动它。牛逼了我的哥,一个通过服务看守桌面程序,不允许关闭的功能实现了。

注意:每次重新编译前要先在服务里将你安装的服务停用

(02)C++ builder之WINDOWS系统服务编写与WINDOWS桌面程序调用相关推荐

  1. Ubuntu 9.04下让Swing和Swt编写的Java桌面程序运行

    本文以Ubuntu 9.04为例 前提:先安装带jre的jdk(下面链接中的文中介绍) http://www.kklinux.com/html/Love-Linux/Ubuntu/200908/05- ...

  2. WINDOWS系统服务详解

    1 WINDOWS系统服务详解    --  WINDOWS系统服务详解 <P>1 Alerter 当系统发生故障时向管理员发送错误警报,除非电脑处于局域网,而且配有网络管理员,一 般不需 ...

  3. windows下编写dll

    dll的优点 简单的说,dll有以下几个优点: 1) 节省内存.同一个软件模块,若是以源代码的形式重用,则会被编译到不同的可执行程序中,同时运行这些exe时这些模块的二进制码会被重复加载到内存中.如果 ...

  4. 全面了解Windows Server 2003 和 Windows XP 附带的系统服务

    简介   系统服务的处理不同于其他设置,因为所有服务的漏洞.对策及潜在影响在本质上都一样.第一次安装 Microsoft Windows Server 2003 时,系统将在启动时创建并配置默认服务. ...

  5. Windows脚本编写

    一.关于脚本语言 脚本语言就是由专用解释器以行为单位解释执行的一种文本形式编程语言,象Windows的批处理.Unix/Linux的shell.perl和awk等脚本语言都属于这个范畴.它们大多都是由 ...

  6. c语言编写系统服务程序,C语言Windows服务程序编写-ServiceMain

    C语言编写的Windows服务程序,可以类比Linux/Unix环境下的daemon进程. 一下是VS2010环境下的demo: // windows_service.cpp : 定义控制台应用程序的 ...

  7. 编写一个Windows服务程序,定时从数据库中拿出记录发送邮件

    前言:编写一个Windows服务程序,定时从数据库中拿出记录发送邮件. 测试环境:Visual Studio 2005 SP1.Windows Server 2003 SP2 一.新建项目 打开VS2 ...

  8. C#中调用Windows系统服务exe程序的工具类与重启服务的流程

    场景 使用C#编写的Windows服务程序,在Winform中进行调用. 常用工具类方法检测服务是否存在或者安装,获取服务状态,启动服务,停止服务的方法. 以在Winform中重启服务为例. 注: 博 ...

  9. windows驱动程序编写_如何在Windows中回滚驱动程序

    windows驱动程序编写 Updating a driver on your PC doesn't always work out well. Sometimes, they introduce b ...

最新文章

  1. 【NLP】不讲武德,只用标签名就能做文本分类
  2. eclipse 搭建Android 开发环境(ADT安装和sdk下载,选择)
  3. Azkaban的介绍、安装与使用
  4. SQL Server系统数据库– msdb数据库
  5. 联手三年,获取数千名客户,阿里云如何重构 Elastic 开放免费的技术?
  6. 最简单的基于FFMPEG的音频编码器(PCM编码为AAC)
  7. Ubuntu修改hosts文件
  8. python3爬虫系列20之反爬需要登录的网站三种处理方式
  9. 【MongoDB】索引属性 之 唯一索引
  10. 智慧农业项目建设体系之精准饲喂系统及数据分析
  11. 机器学习笔记21——决策树之CART算法原理及python实现案例
  12. 【论文阅读 | 冷冻电镜】RELION 4.0 中新的 subtomogram averaging 方法解读
  13. 我为什么既支持又反对接口用Map来传输数据?
  14. Windows Terminal PowerShell 7 美化
  15. python获取excel整行数据如何保存到新的工作簿中_如何使用python将大量数据导出到Excel中的小技巧之一...
  16. 线段树维护(最大区间和,最大子段和,最长连续上升子序列)
  17. InternImage
  18. 计算机收藏夹位于哪个磁盘,电脑浏览器收藏夹保存在哪里
  19. 要把服务器架在太空的海盗湾,为什么能活十五年?
  20. python 手机自动化交易股票_通达信转python,机智股票自动交易手机版

热门文章

  1. 不用找,你想要的医疗化工海外PPT模板素材都在这里
  2. 国际名牌服装有哪些?
  3. 能看能听还能摸,这才是真正的裸眼 3D
  4. google play music不显名字
  5. MAB建模规范-Simulink模型建模规范
  6. Windows安装Python-docx三方库(保姆级教程)
  7. matlab simulink 模糊变论域控制电梯四分之一模型
  8. 谨以此文纪念逝去的SUN
  9. Azure带宽与Azure Blob云存储
  10. 测试用例-------一张白纸