C++语言编写windows服务

C++语言编写windows服务

    • 1 windows服务
    • 2 DebugView调试工具
    • 3 c语言编写windows服务
    • 4 将程序作为windows服务

1、 windows服务

通过快捷键”win+R”打开运行框,输入”services.msc”,就能够打开windows服务。鼠标右键任意一个服务,能看见以下的选项,如下图1.1所示
图1.1 windows服务
本文的内容讲的就是通过windows服务控制程序的启动停止等操作。

2、 DebugView调试工具

官网上是这样介绍这款软件的

我们可以用这款软件来调试windows服务程序。如图2.1进行DebugView的相关设置,并在我们写的程序中使用函数”OutputDebugString”,这时当启动我们写的windows服务,DebugView就能够将程序的调试信息捕捉到,显示出来。
图2.1 将Capture Kernel打上勾

3、 c++语言编写windows服务

c++语言的windows服务的代码如下,此程序已在win7,VS2010调试运行通过。本例的源代码来自代码来源

#include <stdio.h>#include <Windows.h>#define SLEEP_TIME 5000 //间隔时间#define FILE_PATH "C:\\log.txt" //信息输出文件bool brun=false;SERVICE_STATUS servicestatus;SERVICE_STATUS_HANDLE hstatus;int WriteToLog(char* str);void WINAPI ServiceMain(int argc, char** argv);void WINAPI CtrlHandler(DWORD request);int InitService();int WriteToLog(char* str){FILE* pfile;fopen_s(&pfile,FILE_PATH,"a+");if (pfile==NULL){return -1;}fprintf_s(pfile,"%s\n",str);fclose(pfile);return 0;}void WINAPI ServiceMain(int argc, char** argv)
{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("testservice", CtrlHandler);if (hstatus==0){WriteToLog("RegisterServiceCtrlHandler failed");return;}WriteToLog("RegisterServiceCtrlHandler success");//向SCM 报告运行状态servicestatus.dwCurrentState = SERVICE_RUNNING;SetServiceStatus (hstatus, &servicestatus);//在此处添加你自己希望服务做的工作,在这里我做的工作是获得当前可用的物理和虚拟内存信息brun=true;MEMORYSTATUS memstatus;char str[100];memset(str,'\0',100);while (brun){GlobalMemoryStatus(&memstatus);int availmb=memstatus.dwAvailPhys/1024/1024;sprintf_s(str,100,"available memory is %dMB",availmb);WriteToLog(str);Sleep(SLEEP_TIME);}WriteToLog("service stopped");}void WINAPI CtrlHandler(DWORD request)
{switch (request){case SERVICE_CONTROL_STOP:brun=false;servicestatus.dwCurrentState = SERVICE_STOPPED;break;case SERVICE_CONTROL_SHUTDOWN:brun=false;servicestatus.dwCurrentState = SERVICE_STOPPED;break;default:break;}SetServiceStatus (hstatus, &servicestatus);
}void main()
{SERVICE_TABLE_ENTRY entrytable[2];entrytable[0].lpServiceName="testservice";entrytable[0].lpServiceProc=(LPSERVICE_MAIN_FUNCTION)ServiceMain;entrytable[1].lpServiceName=NULL;entrytable[1].lpServiceProc=NULL;StartServiceCtrlDispatcher(entrytable);}

我在写相关的windows服务程序的时候遇到了这样的问题,程序加载当前的路径的配置文件”./config.xml”,发现程序总是在加载文件这个地方出错,然后用函数”GetCurrentDirectory”函数获取程序当前运行的路径,并且用函数”OutputDebugString”将获取到的路径信息打印出来,获取到程序当前的运行目录是”C:\Windows\system32”,要加载程序运行的配置文件,应该使用绝对路径。在windows服务中获取程序的路径。下面两段程序都能获得程序的路径。

//代码一
string GetProgramDir()    
{     TCHAR exeFullPath[MAX_PATH]; // Full path  GetModuleFileName(NULL,exeFullPath,MAX_PATH);  string strPath = __TEXT("");         strPath = exeFullPath;    // Get full path of the file  int pos = strPath.find_last_of(L'\\', strPath.length());  return strPath.substr(0, pos);  // Return the directory without the file name  
} 
//代码二
void GetConfigPath()
{   UINT    nLen  = MAX_PATH;char    process[MAX_PATH] = {0};char    drive[_MAX_DRIVE] = {0};char    dir[_MAX_DIR] = {0};char    fname[_MAX_FNAME] = {0};char    ext[_MAX_EXT] = {0};UINT    nbaselen = 0;UINT    nprocesslen = 0;char *pChrTemp = chConfigPath;memset(pChrTemp,0,MAX_PATH);GetModuleFileName(NULL, process, MAX_PATH);_splitpath_s(process, drive, dir, fname, ext);_makepath_s(process, "", dir, "", "");strcat_s(pChrTemp,nLen-strlen(pChrTemp),drive);nbaselen = (UINT)strlen(pChrTemp);nprocesslen = (UINT)strlen(process);if((nbaselen+nprocesslen)<nLen){   strcat_s(pChrTemp,nLen-strlen(pChrTemp),process);chConfigPath[strlen(chConfigPath)-1] = '\0';}/*while( *pChrTemp) {if( *pChrTemp == '\\') {*pChrTemp = '/';}pChrTemp ++;}*/
}

4、 将程序作为windows服务

windows服务有以下命令,”win+R”后输入”cmd”,即可进行操作

输入sc create testservicename binpath= D:\test.exe (这里的D:\test.exe路径就是你的.exe程序所在的绝对路径,注意"="后面有一个空格)输入sc start testservicename 启动服务输入sc query 会在最底部显示你的服务当前的状态输入sc stop testservicename 停止服务输入sc delete testservicename删除服务,该服务将在下次重启后删除,在重启之前将不能注册同一个名字的服务。

下面是一个简单的startup.bat文件创建windows服务的操作

rem startup.bat 文件创建服务,这里为服务取名为testservicename,此文件放在与.exe文件同级目录下,按着"Shift"键,同时单击鼠标右键,点击"在此处打开命令窗口",然后输入此文件名"startup.bat",就能创建此服务
@echo offrem 获取绝对路径
set "CURRENT_DIR=%~dp0"set "EXE_NAME=testservicename.exe"@echo %CURRENT_DIR%%EXE_NAME%rem 创建windows服务
sc create yzUpgradeService binpath= %CURRENT_DIR%%EXE_NAME%sc config yzUpgradeService start= AUTO 

本文链接:https://my.lmcjl.com/post/6806.html

展开阅读全文

4 评论

留下您的评论.