快速编写简单windows服务程序Word文档格式.docx

上传人:b****3 文档编号:8290283 上传时间:2023-05-10 格式:DOCX 页数:9 大小:20.95KB
下载 相关 举报
快速编写简单windows服务程序Word文档格式.docx_第1页
第1页 / 共9页
快速编写简单windows服务程序Word文档格式.docx_第2页
第2页 / 共9页
快速编写简单windows服务程序Word文档格式.docx_第3页
第3页 / 共9页
快速编写简单windows服务程序Word文档格式.docx_第4页
第4页 / 共9页
快速编写简单windows服务程序Word文档格式.docx_第5页
第5页 / 共9页
快速编写简单windows服务程序Word文档格式.docx_第6页
第6页 / 共9页
快速编写简单windows服务程序Word文档格式.docx_第7页
第7页 / 共9页
快速编写简单windows服务程序Word文档格式.docx_第8页
第8页 / 共9页
快速编写简单windows服务程序Word文档格式.docx_第9页
第9页 / 共9页
亲,该文档总共9页,全部预览完了,如果喜欢就下载吧!
下载资源
资源描述

快速编写简单windows服务程序Word文档格式.docx

《快速编写简单windows服务程序Word文档格式.docx》由会员分享,可在线阅读,更多相关《快速编写简单windows服务程序Word文档格式.docx(9页珍藏版)》请在冰点文库上搜索。

快速编写简单windows服务程序Word文档格式.docx

在ServiceMain中循环,这样服务就开始运行了。

2.ServiceMain函数为voidWINAPIServiceMain(intargc,char**argv)格式的函数,函数名字可以任意定义。

它的作用就是:

将你需要执行的任务放到该函数中循环执行即可。

这就是服务程序的工作函数。

在ServiceMain执行你的任务前,需要给SERVICE_TABLE_ENTRY分派

表结构体进行赋值,注意由于此时服务还没有开始执行你的任务所以我们将服务的状态设置为SERVICE_START_PENDING,即正在初始化。

我们进行如下赋值:

servicestatus.dwServiceType=SERVICE_WIN32;

servicestatus.dwCurrentState=SERVICE_START_PENDING;

servicestatus.dwControlsAccepted=SERVICE_ACCEPT_SHUTDOWN|SERVICE_ACCEPT_STOP;

//在本例中只接受系统关机和停止服务两种控制命令 

servicestatus.dwWin32ExitCode=0;

servicestatus.dwServiceSpecificExitCode=0;

servicestatus.dwCheckPoint=0;

servicestatus.dwWaitHint=0;

hstatus=:

:

RegisterServiceCtrlHandler("

CtrlHandler);

CtrlHandler为voidWINAPICtrlHandler(DWORDrequest)型的函数,函数名字可以任意设定。

将在下一点讲到。

Hstatus为SERVICE_STATUS_HANDLE类型的全局变量。

当需要改变服务状态时SetServiceStatus()函数需要它做为参数来标识一个服务。

3.voidWINAPICtrlHandler(DWORDrequest),函数的主要功能是,接收系统传递的控制命令,比如当你通过sc.exe关闭服务时,该函数会收到SERVICE_CONTROL_STOP消息,你就可以对服务进行必要的管理。

在本例子程序中就只接收SERVICE_ACCEPT_SHUTDOWN和

SERVICE_ACCEPT_STOP消息,这是通过前面给servicestatus赋值设定的。

这样一个基本的服务程序就完成了。

本文结束的时候会附上如

何安装服务。

当服务程序需要使用某些功能时,由于用户的关系而受到限制,比如访问注册表的HKEY_CURRENT_USER键,使用网络等等,这时候就需要以当前登陆用户的身份去进行操作,通常会创建一个进程来完成需要的功能。

如果使用CreateProcess,来创建进程的话,新创建的进程和服务程序依然是相同的用户身份,还是无法达到目的,只有使用CreateProcessAsUser了。

但CreateProcessAsUser的第一个参数是HANDLE 

hToken,该参数通常应该用LogonUser来获得,但是LogonUser又需要用户名和用户密码,这样就很不现实。

那应该怎么办呢?

我想到了一个方法可以绕过LogonUser直接获得hToken。

因为用户已经登陆,那么肯定有Shell(就是EXPLORER.EXE)运行了,我们可以通过遍历进程来取得Shell的hToken来运行进程。

因此需要

BOOLGetTokenByName(HANDLE&

hToken,LPSTRlpName);

BOOLRunProcess(LPCSTRlpImage);

两个函数

示例是关于基于opencv人脸识别,遍历样本文件夹,删除多余的图片保留10张, 

然后执行外部自定义程序"

GetFeatureDATA.exe"

函数提取特征

GetFeatureDATA.exe中最头上加上#pragmacomment(linker,"

/subsystem:

\"

Windows\"

/entry:

mainCRTStartup\"

"

)就可以隐藏控制台窗口

开发环境vs2010,控制台应用程序.

//服务程序主函数。

#include"

stdio.h"

vector"

Tlhelp32.h"

#include<

afx.h>

#define_AFXDLL

//由于做的图像识别需要opencv头文件,需要什么文件自行更改

cv.h"

highgui.h"

usingnamespacestd;

//你的服务程序需要以下代码

SERVICE_STATUSservicestatus;

SERVICE_STATUS_HANDLEhstatus;

//全局变量.是setServiceStatus()的参数,改变服务状态

voidWINAPIServiceMain(intargc,char**argv);

voidWINAPICtrlHandler(DWORDrequest);

boolbrun=false;

//原来代码有的,我没有用,还是保留

//以下是以获取登录用户名

//自己添加的代码

inttrain_time;

//以分钟计

vector<

CString>

Vec_Dir;

//存放图片文件夹目录名称

Vec_Img;

//

voidTraverseDir(CString&

strDir,std:

&

vecDir);

intTraverseImg(CString&

vecFile);

vecDir)

{

WIN32_FIND_DATAFindFileData;

CStringstrDirTmp;

strDirTmp=strDir;

strDirTmp+="

\\*.*"

HANDLEhFind=:

FindFirstFile(strDirTmp,&

FindFileData);

if(INVALID_HANDLE_VALUE==hFind)

{

return;

}

while(TRUE)

if(FindFileData.dwFileAttributes&

FILE_ATTRIBUTE_DIRECTORY)

if(FindFileData.cFileName[0]!

=_T('

.'

))

\\"

strDirTmp+=FindFileData.cFileName;

vecDir.push_back(strDirTmp);

//保存所有目录

//TraverseDir(strDirTmp,vecFile);

else//是文件

/*strDirTmp=strDir;

vecFile.push_back(strDirTmp);

*/

if(!

FindNextFile(hFind,&

FindFileData))

break;

FindClose(hFind);

}

vecFile)//输入路径,得到img路径文件名

intImgNum=0;

//return;

TraverseDir(strDirTmp,vecFile);

else

//将图片路径传入

ImgNum++;

returnImgNum;

voidWINAPIServiceMain(intargc,char**argv)

servicestatus.dwServiceType=SERVICE_WIN32;

servicestatus.dwControlsAccepted=SERVICE_ACCEPT_SHUTDOWN|SERVICE_ACCEPT_STOP;

//在本例中只接受系统关机和停止服务两种控制命令

hstatus=:

if(hstatus==0)

{

//WriteToLog("

RegisterServiceCtrlHandlerfailed"

);

}

RegisterServiceCtrlHandlersuccess"

//向SCM报告运行状态

servicestatus.dwCurrentState=SERVICE_RUNNING;

SetServiceStatus(hstatus,&

servicestatus);

//下面就开始任务循环了,你可以添加你自己希望服务做的工作

brun=true;

//MEMORYSTATUSmemstatus;

//charstr[100];

//memset(str,'

\0'

100);

//while(brun)

//{

//GlobalMemoryStatus(&

memstatus);

//intavailmb=memstatus.dwAvailPhys/1024/1024;

//sprintf_s(str,100,"

availablememoryis%dMB"

availmb);

//WriteToLog(str);

//Sleep(SLEEP_TIME);

//}

servicestopped"

//

//以下是自己要写的代码的执行调用地方

//SYSTEMTIMEt;

//GetLocalTime(&

t);

//inthour=t.wHour;

//获取小时,可以在固定某个小时执行程序

while

(1)//

CStringSamplesDirPath=_T("

G:

\\Samples"

TraverseDir(SamplesDirPath,Vec_Dir);

//获取目录名称到vec_Dir

for(inti(0);

i<

Vec_Dir.size();

i++)//

intImg_Num=TraverseImg(Vec_Dir[i],Vec_Img);

//某个目录下的所有图片

if(Img_Num>

10)

for(intj=Img_Num-10-1;

j>

=0;

j--)

remove(Vec_Img[j]);

Vec_Img.clear();

//执行提取xml文件exe文件

//WinExec("

\\about_MFC\\GetFeatureDATA.exe"

0);

//system("

GetFeatureDATA.exe"

//ShellExecute(NULL,"

open"

"

NULL,NULL,SW_SHOWNORMAL);

RunProcess("

//从硬盘里读取时间来做个每隔多少时间进行

CvFileStorage*Threshold=cvOpenFileStorage("

./service_time.xml"

0,CV_STORAGE_READ);

//读取预值

CvFileNode*ThresholdNode=cvGetFileNodeByName(Threshold,0,"

circle_time"

doubleservice_time=cvReadRealByName(Threshold,ThresholdNode,"

Sleep(service_time*60*1000);

//sleep自定时间后再次执行操作

}

hToken,LPSTRlpName)

{

lpName)

returnFALSE;

HANDLEhProcessSnap=NULL;

BOOLbRet=FALSE;

PROCESSENTRY32pe32={0};

hProcessSnap=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);

if(hProcessSnap==INVALID_HANDLE_VALUE)

return(FALSE);

pe32.dwSize=sizeof(PROCESSENTRY32);

if(Process32First(hProcessSnap,&

pe32))

do

strcmp(_strupr(pe32.szExeFile),_strupr(lpName)))

HANDLEhProcess=OpenProcess(PROCESS_QUERY_INFORMATION,

FALSE,pe32.th32ProcessID);

bRet=OpenProcessToken(hProcess,TOKEN_ALL_ACCESS,&

hToken);

CloseHandle(hProcessSnap);

return(bRet);

while(Process32Next(hProcessSnap,&

pe32));

bRet=TRUE;

else

bRet=FALSE;

BOOLRunProcess(LPCSTRlpImage)

lpImage)

HANDLEhToken;

GetTokenByName(hToken,"

EXPLORER.EXE"

STARTUPINFOsi;

PROCESS_INFORMATIONpi;

ZeroMemory(&

si,sizeof(STARTUPINFO));

si.cb=sizeof(STARTUPINFO);

si.lpDesktop=TEXT("

winsta0\\default"

BOOLbResult=CreateProcessAsUser(hToken,lpImage,NULL,NULL,NULL,

FALSE,NORMAL_PRIORITY_CLASS,NULL,NULL,&

si,&

pi);

CloseHandle(hToken);

if(bResult)

OutputDebugString("

CreateProcessAsUserok!

\r\n"

CreateProcessAsUserfalse!

returnbResult;

然后安装服务运行cmd.exe

输入以下:

sccreateyour_service_namebinpath=D:

\backup\GetXML.exe 

//这步注意等号右边有个空格

scstart 

your_service_name 

//启动服务,也可以启动任务管理器在服务一栏中找到你的服务启动或停止

scstoptestservicename 

//停止服务

scdeletetestservicename//删除服务,该服务将在下次重启后删除,在重启之前将不能注册

同一个名字的服务。

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 小学教育 > 语文

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2