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

(中行雷威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,如果程序已经启动则不动作,否则就启动它。牛逼了我的哥,一个通过服务看守桌面程序,不允许关闭的功能实现了。

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


上篇 C++ Builder入门 第一章 C++ Builder 5的集成开发环境 1.1 概述 1.1.1 C++ Builder 5的主要特点 1.1.2 C++ Builder 5的新增功能 1.1.3 C++ Builder 5的安装与运行 1.2 C++ Builder 5的集成开发环境 1.2.1 窗体 1.2.2 菜单栏 1.2.3 加速栏 1.2.4 控件栏 1.2.5 对象观察器 1.2.6 工程管理器 1.2.7 代码编辑器 1.2.8 类浏览器 1.2.9 桌面工具栏 1.3 C++ Builder的编程方法和步骤 1.3.1 开始一个新的工程 1.3.2 设计用户界面 1.3.3 属性的设置 1.3.4 编写程序代码 1.3.5 编译、运行程序 1.4 程序的调试 1.4.1 程序错误的种类 1.4.2 C++ Builder集成环境中的调试选项 1.4.3 C++ Builder的主要调试手段 1.4.4 C++ Builder的辅助调试工具 1.5 使用联机帮助 1.6 小结 第二章 窗体 2.1 窗体的属性、事件和方法 2.1.1 窗体的主要属性 2.1.2 窗体的主要事件 2.1.3 窗体的方法 2.2 设置窗体环境 2.3 窗体模板 2.3.1 使用窗体模板 2.3.2 向窗体模板库中加入新的窗体模板 2.4 菜单设计 2.5 菜单项的主要属性和方法 2.6 菜单模板 2.7 工具栏设计 2.8 状态栏设计 2.9 综合实例 2.10 小结 第三章 常用控件编程 3.1 进度条控件(ProgressBar) 3.1.1 进度条捷件的属性 3.1.2 进度条控件的入法 3.2 动画控件(Animate) 3.2.1 动画控件的属性 3.2.2 动画控件的主要方法 3.3 列表框控件(ListBox) 3.3.1 列表框控件的属性 3.3.2 列表框的主要方法 3.4 组合框控件(ComboBox) 3.4.1 组合框拧件的属性 3.4.2 组合框控件的方法 3.5 列表视图控件的属性(ListView) 3.6 树形视图控件(TreeView) 3.7 文件系统控件 3.7.1 文件列表框控件(FileList) 3.7.2 驱动器组合框控件(DriveComboBox) 3.7.3 过滤器组合框控件(FilterComboBox) 3.7.4 目录列表框控件(DirectoryListBox) 3.8 公用对话枢控件 3.8.1 OpenDialog的主要属性 3.8.2 OpenDialog的方法——Execute方法 3.9 文本编辑校件(RichEdit) 3.9.1 文本编辑控件的主要属性 3.9.2 文本编辑校件的方法 3.10 小结 第四章 消息及异常 4.1 Windows消息和C++ Builder事件 4.2 消息映射 4.3 自定义消息 4.3.1 定义自己的消息 4.3.2 定义消息处理旬柄 4.3.3 发送和传递消息 4.4 异常处理 4.5 try/catch块 4.6 异常类 4.7 替代缺省的异常处理 4.8 小结 中篇 C++ Builder进阶 第五章 图形和图像 5.1 图形功能 5.1.1 画布(Canvas)的属性 5.1.2 画布对象的常用方法 5.2 图像功能 5.2.1 TGraphic类 5.2.2 TPicture类 5.2.3 TImage组件及其应用 5.2.4 TShape组件 5.3 图形和图像的综合 5.3.1 组件设计 5.3.2 代码设计 5.4 小结 第六章 多媒体 6.1 多媒体与MCI Media Player 6.2 用MediaPlayer控件进行编程 6.2.1 MediaPlayer的主要属性及事件 6.2.2 使用MediaPlayer控件 6.3 运用MCI API进行多媒体开发 6.3.1 PlaySound函数 6.3.2 mciSendString 6.3.3 mciSendCommand 6.4 ActiveMovie控件 6.4.1 ActiveMovie控件的主要属性 6.4.2 ActvieMovie的主要方法 6.4.3 ActiveMovie的主要事件 6.5 小结 第七章 OpenGL和DirectDraw 7.1 OpenGL 7.2 DirectDraw 7.2.1 DirectX 7.2.2 DirectDraw的概述 7.3 DirectDraw、OLE和COM接口 7.3.1 DirectDraw对象和IDirectDraw接口 7.3.2 DirectDrawClipper对象和IDirectDrawClipper接口 7.3.3 DirectDraw
相关推荐
C++Builder 资料库 提供50多个例子,带目录 1.怎样在C++Builder中创建使用DLL 2.用C++Bulider在WIN.INI中保存信息 3.如何在C++Builder中检测硬件 4.C++Builder如何响应消息及自定义消息 5.利用C++ Builder开发动画DLL 6.用C++ Builder 3制作屏幕保护程序 7.TCP/IP头格式 8.UDP 9.判断windows的Desktop及其它目录 10用C++Builder创建数字签名 11用Enter 键控制焦点切换的方法 12.拦 截 Windows 消 息 13.使用CommaText 14.程序开始时先显示信息框 15.怎样获取程序的命令行参数? 16.如何监视剪贴板 17.如何使用OnIdle事件 18.用C++Builder编写串行异步通信程序 19.C++BUILDER非可视组件的消息处理技巧 20.用C++Builder 建立数据库VCL使用经验 21.用C++ Builder创建基于Internet的点对点Chat 22.用C++Builder获取应用程序图标 23.BIG5到GB的转换技术 24.C++BUILDER让你的任务栏图标动起来 25.TFORM 26.用BCB在windows桌面创建快捷方式 27.读磁片磁区 28.I/O 端口读写的实现 29.检测鼠标位置 30.令Win32 应用程序跳入系统零层 31.如何取得Memo的行和列 32.使用Sockets 33.Windows95/98下怎样隐藏应用程序不让它出现在CTRL-ALT-DEL对话框中? 34.怎样隐藏应用程序的任务条图标 35.编写自己的Ping.exe程序 36.用C++Builder在WINNT下编制一个Service 37.如何在C++ BUILDER中自动关闭WINDOWS屏保 38.显示/隐藏任务栏图标 39.信箱监视程序 40.C++Building制作闹钟 41.拨号上网IP地址的检知 42.用C++ Builder编写Tray程序 43.怎样用代码来最小化或恢复程序 44.制作主窗口显示前的版权窗口 45.判断是否已经联到 internet 46.获取登陆用户名 47.隐藏桌面图标 48.程序启动时运行 49.控制面板的调用 50.模拟键盘按键 51.让标题栏闪烁 52.启动屏幕保护 53.年月日星期的取法 54.键盘事件 55.隐藏任务栏 56.禁止关机 57.怎样以最小化方式启动程序 58.在Memo中增加一行后,如何使最后一行能显示 59.设置壁纸方法
©️2020 CSDN 皮肤主题: 编程工作室 设计师:CSDN官方博客 返回首页