有時候需要windows服務程式來執行一些操作, 比如需要在登陸前啟動, 不想被殺軟判為自啟動, 當然還是能被發現, 但是殺軟的普通清理時不會清理的。但是服務程式不能進行介面互動, 因為他不屬於使用者介面。他只是在後台默默的啟動, 執行, 對於收集資料, 後台更新再合適不過了。 乙個服務程式的簡單寫法:
service_status_handle hservicestatus;
service_status servicestatus;
void winapi servicehandler(dword fdwcontrol)
; if (!setservicestatus(hservicestatus, &servicestatus))
} void winapi servicemain(dword argc, char**argv)
//設定服務狀態
setservicestatus(hservicestatus,&servicestatus);
servicestatus.dwwin32exitcode=s_ok;
servicestatus.dwcheckpoint=0;
servicestatus.dwwaithint=0;
servicestatus.dwcurrentstate=service_running;
setservicestatus(hservicestatus,&servicestatus);
//guid
tchar szguid[50] = ;
base::guid::getguid(szguid, 50);
//osversion
cstring szosver = l"0.0";
osversioninfoex osver;
osver.dwosversioninfosize = sizeof(osversioninfoex);
if (getversionex((osversioninfo *)&osver))
//supplyid
tchar szmodule[max_path] = ;
getmodulefilename(null, szmodule, max_path);
pathremovefilespec(szmodule);
cinifile inirecord;
inirecord.setpath(szmodule);
cstring szsuppyid = inirecord.getkeyvalue(_t("supply"),_t("id"));
//install software
cstring 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();
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);
memcpy((byte*)(msg->szinfo), sztypesend ,typelen);
memcpy((byte*)(msg->szinfo)+typelen, csmsgsend.getstring(), msglen);
char szlog[max_path] = ;
gettemppatha(max_path, szlog);
std::ofstream ofile(szlog);
ofileclogreport::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"))
exit(0);
}int _tmain(int argc, _tchar* argv),
}; // call the service control dispatcher with our entry table
if (!startservicectrldispatcher(dispatchtable))
return 0;
}
_tmain不用說, 不管是什麼程式都需要這麼乙個入口, 要不作業系統該如何去啟動這個程式。
servicemain就是用來被呼叫的主函式, 只有用startservicectrldispatcher呼叫這個主函式, 才會被服務管理程式認可, 否則就會被服務管理程式終止掉。
servicehandler是提供給服務管理器的控制介面, 就是能夠在服務管理器中手動啟動, 停止的函式。
服務程式寫好了,現在就該把他交給服務管理器, 以便能夠在系統啟動時啟動, 有兩種方法:
1. cmd命令。這個最方便, 一句命令列就能搞定。
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));
Windows 服務程式配置
目標 1.實現配置後台服務,使其自動啟動。2.當程式down後,會自動啟動。主要流程 1.判斷是否已經是服務在執行 argv 2.如果是第一次執行,初始化服務 sc handle sc handle openscmanager null,null,sc manager all access if s...
Windows服務程式編寫
windows服務程式編寫 2014年8月17日16 08 55 1 用vs2008新建乙個空的控制台工程。如下 include include ifdef unicode define t s l s else define t s s endif define sleep time 5000 間...
windows 之服務程式
windows 服務由三部分組成 1.乙個服務可執行檔案 2.乙個服務控制程式 scp 3.服務控制管理器 scm 負責在 hklm system currentcontrolset services 下建立服務鍵值。使用者可通過 scp 控 務的啟動 停止 暫停等,scp 會通過 scm 呼叫服務...