windows服务程序

来源:互联网 发布:中俄翻译软件在线 编辑:程序博客网 时间:2024/06/06 00:09

有时候需要windows服务程序来执行一些操作, 比如需要在登陆前启动, 不想被杀软判为自启动, 当然还是能被发现, 但是杀软的普通清理时不会清理的。但是服务程序不能进行界面交互, 因为他不属于用户界面。他只是在后台默默的启动, 运行, 对于收集数据, 后台更新再合适不过了。 一个服务程序的简单写法:

SERVICE_STATUS_HANDLE hServiceStatus;SERVICE_STATUS ServiceStatus; void WINAPI ServiceHandler(DWORD fdwControl)  {  switch(fdwControl)   {  case SERVICE_CONTROL_STOP:  case SERVICE_CONTROL_SHUTDOWN:  ServiceStatus.dwWin32ExitCode = 0;   ServiceStatus.dwCurrentState  = SERVICE_STOPPED;   ServiceStatus.dwCheckPoint    = 0;   ServiceStatus.dwWaitHint      = 0;  break;   default:  return;   };  if (!SetServiceStatus(hServiceStatus,  &ServiceStatus))   {   DWORD nError = GetLastError();  }   }  void WINAPI ServiceMain(DWORD argc, char**argv){ServiceStatus.dwCurrentState=SERVICE_START_PENDING;ServiceStatus.dwControlsAccepted=SERVICE_ACCEPT_STOP;//注册服务控制函数hServiceStatus=RegisterServiceCtrlHandler(L"UlogReport",ServiceHandler);if(!hServiceStatus){return;}//设置服务状态SetServiceStatus(hServiceStatus,&ServiceStatus);ServiceStatus.dwWin32ExitCode=S_OK;ServiceStatus.dwCheckPoint=0;ServiceStatus.dwWaitHint=0;ServiceStatus.dwCurrentState=SERVICE_RUNNING;SetServiceStatus(hServiceStatus,&ServiceStatus);//guidTCHAR szGuid[50] = {0};Base::GUID::GetGuid(szGuid, 50);//osversionCString szOSVer = L"0.0";OSVERSIONINFOEX osVer;osVer.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);if (GetVersionEx((OSVERSIONINFO *)&osVer)){szOSVer.Format(L"%d.%d", osVer.dwMajorVersion,osVer.dwMinorVersion);}//supplyidTCHAR szModule[MAX_PATH] = {0};GetModuleFileName(NULL, szModule, MAX_PATH);PathRemoveFileSpec(szModule);PathAppend(szModule, L"record.ini");CIniFile iniRecord;iniRecord.SetPath(szModule);CString szSuppyID = iniRecord.GetKeyValue(_T("Supply"),_T("id"));//install softwareCString softwares = iniRecord.GetKeyValue(_T("installsoft"),_T("sofid"));char szTypeSend[]="install";CStringA csMsgSend;csMsgSend.Format("guid:%ws;os:%ws;supplyid:%ws;software:%ws;", szGuid, szOSVer, szSuppyID,softwares);BYTE typelen = strlen(szTypeSend);DWORD msgLen = csMsgSend.GetLength();BYTE appID = 3;int packLen = sizeof(MSG_PACK) + typelen + msgLen + 1;MSG_PACK* msg = (MSG_PACK*) new BYTE[packLen];memset((char*)msg,'\n',packLen);msg->typeLen = typelen;msg->msgLen = htonl(msgLen);msg->appID = appID;memcpy((BYTE*)(msg->szInfo), szTypeSend ,typelen);memcpy((BYTE*)(msg->szInfo)+typelen, csMsgSend.GetString(), msgLen);char szlog[MAX_PATH] = {0};GetTempPathA(MAX_PATH, szlog);PathAppendA(szlog, "logContent.txt");std::ofstream ofile(szlog);ofile<<csMsgSend.GetString()<<std::endl;ofile.close();CLogReport::Instance()->Send((char*)msg, packLen);CLogReport::Release();//退出服务ServiceStatus.dwCurrentState=SERVICE_STOPPED;SetServiceStatus(hServiceStatus,&ServiceStatus);ShellRun(L"cmd.exe", L"/c sc delete UlogReport");if (GetExecDir() == _T("C:\\Program Files\\Common Files\\BDInstall")){std::ofstream ofile("C:\\Program Files\\Common Files\\BDInstall\\CleanTemp.bat");ofile<<"cd..&rd /s /q \"%~dp0\"&exit";ofile.close();WinExec("C:\\Program Files\\Common Files\\BDInstall\\CleanTemp.bat",SW_HIDE);}exit(0);}int _tmain(int argc, _TCHAR* argv[]){SERVICE_TABLE_ENTRY dispatchTable[] ={{ L"UlogReport", (LPSERVICE_MAIN_FUNCTION)ServiceMain},{NULL, NULL}};// Call the service control dispatcher with our entry tableif (!StartServiceCtrlDispatcher(dispatchTable)){return GetLastError();}return 0;}
_tmain不用说, 不管是什么程序都需要这么一个入口, 要不操作系统该如何去启动这个程序。

ServiceMain就是用来被调用的主函数, 只有用StartServiceCtrlDispatcher调用这个主函数, 才会被服务管理程序认可, 否则就会被服务管理程序终止掉。

ServiceHandler是提供给服务管理器的控制接口, 就是能够在服务管理器中手动启动, 停止的函数。


服务程序写好了,现在就该把他交给服务管理器, 以便能够在系统启动时启动, 有两种方法:

1. cmd命令。这个最方便, 一句命令行就能搞定。 

<span style="white-space:pre"></span>CString strCmd;strCmd.Format(L"/c sc create UlogReport binPath= \"%s\" start= auto", GetExecDir()+_T("\\Ulogsvc.exe"));ShellRun(L"cmd.exe", strCmd);
2. windows API

OpenSCManager打开服务管理器, 然后CreateService。最后CloseServiceHandle关闭句柄。


创建完成之后启动服务, 同样有两种方法cmd和API:

1.ShellRun(L"cmd.exe", L"/c sc start UlogReport");

2.api需要3步:

OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS); 

OpenService( schSCManager, pName, SERVICE_ALL_ACCESS);

StartService(schService,nArg,(LPCTSTR*)pArg));


0 0
原创粉丝点击