人亦已歌 发表于 2023-2-17 19:03:50

使用windowsAPI编写一个系统服务程序 完整的编写逻辑


#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#define SLEEP_TIME 5000
#define FILE_PATH "c:\\log.txt"
BOOL bRunning;
void WINAPI ServiceMain(int argc,char** argv);
void WINAPI ServiceCtrlHandler(DWORD Opcode);
SERVICE_STATUS m_ServiceStatus;
SERVICE_STATUS_HANDLE m_ServiceStatusHandle;
int WriteToLog(char* str);

void main(void){
      SERVICE_TABLE_ENTRY DispatchTable;
      DispatchTable.lpServiceName="demo";
      DispatchTable.lpServiceProc=(LPSERVICE_MAIN_FUNCTION)ServiceMain;
      DispatchTable.lpServiceName=NULL;
      DispatchTable.lpServiceProc=NULL;

      StartServiceCtrlDispatcher(DispatchTable);//注册服务主函数

}

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){
      MEMORYSTATUS memstatus;
      char str;
      int availmb;
      m_ServiceStatus.dwServiceType=SERVICE_WIN32;
      m_ServiceStatus.dwCurrentState=SERVICE_START_PENDING;
      m_ServiceStatus.dwControlsAccepted=SERVICE_ACCEPT_SHUTDOWN|SERVICE_ACCEPT_STOP;
      m_ServiceStatus.dwWin32ExitCode=0;
      m_ServiceStatus.dwServiceSpecificExitCode=0;
      m_ServiceStatus.dwCheckPoint=0;
      m_ServiceStatus.dwWaitHint=0;


      //注册服务控制函数
      m_ServiceStatusHandle = RegisterServiceCtrlHandler("demo",ServiceCtrlHandler);
      if(m_ServiceStatusHandle==0){
                WriteToLog("写出失败日志");
                return;
      }
      WriteToLog("写出成功日志");
      m_ServiceStatus.dwCurrentState=SERVICE_RUNNING;
      SetServiceStatus(m_ServiceStatusHandle,&m_ServiceStatus);
      bRunning=TRUE;
      memset(str,'\0',100);
      while(bRunning){
                GlobalMemoryStatus(&memstatus);
                availmb=memstatus.dwAvailPhys/1024/1024;
                sprintf_s(str,100,"可用内存的大小是%dMB",availmb);
                WriteToLog(str);//每隔5秒写出执行日志
                Sleep(SLEEP_TIME);
      }
      WriteToLog("服务停止写出日志");
}

void WINAPI ServiceCtrlHandler(DWORD Opcode){
      switch(Opcode){
      case SERVICE_CONTROL_STOP:
                bRunning=FALSE;
                m_ServiceStatus.dwCurrentState=SERVICE_STOPPED;
                break;
      case SERVICE_CONTROL_SHUTDOWN:
                bRunning=FALSE;
                m_ServiceStatus.dwCurrentState=SERVICE_STOPPED;
                break;
      default:
                break;
      }
      SetServiceStatus(m_ServiceStatusHandle,&m_ServiceStatus);
}




生成后cmd执行sc命令安装服务
sc create demo3 binpath= c:\demo3.exe





启动服务后完美运行并写出日志




以上代码生成的可执行服务程序


关闭服务
sc stop demo3

卸载服务
sc delete demo3


dbvdb 发表于 2023-2-18 20:27:16

中国太需要有志之士了,愿大家都共同努力吧!

myfavorcn 发表于 2023-2-19 17:34:48

很受看!

硅谷 发表于 2023-2-20 08:39:48

我不是计算机系的,但是也想从事程序员之类的工作,今年找工作,遇到种种挫折,今天读到这篇文章,受益匪浅啊!非常感谢,值得深思!

czr 发表于 2023-2-21 02:50:03

是呀也许这就是中国教育饿偏差吧?非常感谢上文的作者的经验之谈,对于我们这些还没有出炉的是一笔宝贵的财富!!!!

meidi 发表于 2023-2-21 19:57:19

这的确是很多编程者的误区,谢谢,让我们少走弯路了!!

娟娟 发表于 2023-2-26 19:45:10

^其实不光是计算机编程,其他学术方面也有同样问题,大学,中学,甚至小学教学都只是完成任务式的教育从不理会学生该怎么样,这是中国教育体制问题

zfh5288 发表于 2023-2-28 19:54:18

受益匪浅。。。。。

爱情病毒 发表于 2023-3-1 13:58:25

我非常同意10楼的意见,真的是写出了我们的心声,真是谢谢了

古竹 发表于 2023-3-3 15:08:22

说了确实是有点热血沸腾...有些时候一个问题并不是一会儿就能找到最好方法的所以每当写一行程序时就应想想当运行到这时会怎么样想的多了大脑也就精了最顶楼那个面试官难道是一开始就想到了用那种方法有规律的才能有最简的方法-----只是一时没想到而已另外我就不懂离散数学是什么样的(是估计值吗)
页: [1] 2 3 4
查看完整版本: 使用windowsAPI编写一个系统服务程序 完整的编写逻辑