青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

隨筆 - 14, 文章 - 0, 評(píng)論 - 3, 引用 - 0
數(shù)據(jù)加載中……

[轉(zhuǎn)貼]Windows服務(wù)程序編程入門

Windows服務(wù)程序是在操作系統(tǒng)后臺(tái)運(yùn)行的一種程序,要開發(fā)該類程序,需要使用windows提供的service API,
MSDN上有對(duì)該類api的詳細(xì)描述,這里簡(jiǎn)單介紹下windows服務(wù)編程的具體步驟:

1.window服務(wù)的安裝
鼠標(biāo)右擊"我的電腦 -〉管理"可以打開計(jì)算機(jī)管理器,進(jìn)入到服務(wù)控制管理界面,這里可以看到所有的服務(wù)
列表(注意所有這些服務(wù)名都存儲(chǔ)在window系統(tǒng)數(shù)據(jù)庫(kù)中),可以選擇每一項(xiàng)服務(wù)進(jìn)行啟動(dòng)或停止等管理操作,我們第一部介紹的就是如何把一項(xiàng)新的服務(wù)寫入這個(gè)服務(wù)控制管理頁(yè)面里,這里我們使用一個(gè)installSercices函數(shù)實(shí)現(xiàn)這一功能,該函數(shù)使用OpenSCManager(WIN API)打開服務(wù)控制管理器獲取的句柄,然后使用CreateService(WIN API)來創(chuàng)建一個(gè)新的服務(wù)。
///安裝服務(wù)
int installServices(const char* szName)
{

///這里的path是利用服務(wù)啟動(dòng)的對(duì)應(yīng)的exe程序路徑
///一般情況下,啟動(dòng)一個(gè)服務(wù),任務(wù)管理器中你可以可到該服務(wù)對(duì)應(yīng)的進(jìn)程被打開運(yùn)行起來。
char szPath[1024]={0};
if(!GetModuleFileName(NULL, szPath, 1024))
return -1;

///打開服務(wù)控制管理器
SC_HANDLE hSCM = OpenSCManager(
NULL, //主機(jī)名,NULL表示本地
NULL, //服務(wù)數(shù)據(jù)庫(kù)名,NULL默認(rèn)為 SERVICES_ACTIVE_DATABASE
SC_MANAGER_ALL_ACCESS //期待獲取到服務(wù)管理器權(quán)限,具體權(quán)限參考msdn
);
if(!hSCM)
return -1;

///創(chuàng)建一個(gè)服務(wù)
SC_HANDLE hSS = CreateService(
hSCM,
szName, ///服務(wù)名
szName, ///服務(wù)控制管理器上的顯示名
SC_MANAGER_ALL_ACCESS, ///服務(wù)控制權(quán)限
SERVICE_WIN32_OWN_PROCESS, /// 服務(wù)類型
SERVICE_DEMAND_START, ///服務(wù)啟動(dòng)方式SERVICE_DEMAND_START
SERVICE_ERROR_NORMAL, ///服務(wù)啟動(dòng)錯(cuò)誤處理方式
szPath, ///服務(wù)程序路徑
NULL,
NULL,
NULL, ///依賴服務(wù)
NULL, ///服務(wù)所屬用戶
NULL ///用戶密碼
);
if(!hSS)
return -1;

if(hSS)
CloseServiceHandle(hSS);

if(hSCM)
CloseServiceHandle(hSCM);

return 0;
}

2. 服務(wù)的啟動(dòng)
我們編寫一個(gè)ServiceStart用來啟動(dòng)服務(wù),啟動(dòng)服務(wù)的主要win api為OpenService 打開已存在的服務(wù)獲取服務(wù)句柄,QueryServiceStatus 獲取服務(wù)當(dāng)前狀態(tài),StartService來啟動(dòng)服務(wù),一般情況下,啟動(dòng)一個(gè)服務(wù),任務(wù)管理器中你可以可到該服務(wù)對(duì)應(yīng)的進(jìn)程被打開運(yùn)行起來。像啟動(dòng)apache服務(wù)對(duì)應(yīng)的進(jìn)程為httpd.exe等。該函數(shù)就像你在服務(wù)控制管理器中選中某一服務(wù)項(xiàng)后右鍵啟動(dòng)。
///啟動(dòng)服務(wù)
int ServiceStart(const char* szName)
{
///打開服務(wù)控制管理器
SC_HANDLE hSCM = OpenSCManager(
NULL, //主機(jī)名,NULL表示本地
NULL, //服務(wù)數(shù)據(jù)庫(kù)名,NULL默認(rèn)為 SERVICES_ACTIVE_DATABASE
SC_MANAGER_ALL_ACCESS //期待獲取到服務(wù)管理器權(quán)限,具體權(quán)限參考msdn
);
if(!hSCM)
return -1;

///打開服務(wù)
SC_HANDLE hSS = OpenService(
hSCM,
szName,
SERVICE_ALL_ACCESS
);
if (!hSS)
goto END;

int iState = SERVICE_START_PENDING;
SERVICE_STATUS status = {0};
status.dwControlsAccepted=SERVICE_ACCEPT_STOP; ///指定該服務(wù)允許被停止
status.dwServiceType=SERVICE_WIN32_OWN_PROCESS;
status.dwCurrentState=SERVICE_STOPPED;
///先檢測(cè)服務(wù)程序是否已經(jīng)運(yùn)行
for(int i=0;i < 300; i++)
{

if(!QueryServiceStatus(hSS, &status))
goto END;

iState = status.dwCurrentState;
if(status.dwCurrentState == SERVICE_RUNNING)
goto END;

if (status.dwCurrentState == SERVICE_STOPPED)
{
break;
}
if (status.dwCurrentState == SERVICE_START_PENDING
|| status.dwCurrentState == SERVICE_STOP_PENDING)
{
Sleep(10);
continue;
}
}

if(!StartService(
hSS,
0, ///參數(shù)個(gè)數(shù)
NULL ///參數(shù)列表
))
{

//goto END;
DWORD err = GetLastError();
err = 0;
}

for(int i=0;i < 300; i++)
{

if(!QueryServiceStatus(hSS, &status))
goto END;

iState = status.dwCurrentState;
if(status.dwCurrentState == SERVICE_RUNNING)
break;

if (status.dwCurrentState == SERVICE_START_PENDING)
{
Sleep(10);
continue;
}
}
if(status.dwCurrentState==SERVICE_RUNNING)
ControlService(hSS, SERVICE_CONTROL_CONTINUE, &status);
END:
if(hSS)
CloseServiceHandle(hSS);
if (hSCM)
CloseServiceHandle(hSCM);

return iState;

}

3. 服務(wù)的停止
開啟服務(wù)后我們也會(huì)使用停止服務(wù)的功能,這里給出一個(gè)停止服務(wù)的的函數(shù)ServiceStop,可以看出該函數(shù)與ServiceSart的代碼差別不大,ServiceStop使用ControlService(WIN API )給運(yùn)行中的程序發(fā)送一個(gè)SERVICE_CONTROL_STOP消息,運(yùn)行中的程序收到該消息后便退出。就像你停止了apapche服務(wù)后,httpd.exe收到SERVICE_CONTROL_STOP消息并退出進(jìn)程。該函數(shù)就像你在服務(wù)控制管理器中選中某一服務(wù)項(xiàng)后右鍵停止效果。ServiceStop函數(shù)實(shí)現(xiàn)了停止服務(wù)和刪除服務(wù)的功能,所以我們?cè)谙乱徊浇榻B服務(wù)的刪除給出代碼。

4. 服務(wù)的刪除
當(dāng)我們不需要這項(xiàng)服務(wù)的時(shí)候我們可以在winows服務(wù)控制管理器中刪除該服務(wù)(當(dāng)然你已可以使用windwo控制臺(tái)使用命令 sc 命令來實(shí)現(xiàn)),使用DeleteService(win api)可以實(shí)現(xiàn)這一點(diǎn),下面是ServiceStop函數(shù),當(dāng)她的第二個(gè)參數(shù)被指定為真實(shí),我們?cè)谕V狗?wù)后會(huì)刪除該服務(wù)。
///停止或刪除服務(wù)
int ServiceStop(const char* szName,bool bDelService=false)
{
int iState = -1;
///打開服務(wù)控制管理器
SC_HANDLE hSCM = OpenSCManager(
NULL, //主機(jī)名,NULL表示本地
NULL, //服務(wù)數(shù)據(jù)庫(kù)名,NULL默認(rèn)為 SERVICES_ACTIVE_DATABASE
SC_MANAGER_ALL_ACCESS //期待獲取到服務(wù)管理器權(quán)限
);
if(!hSCM)
return -1;

///打開服務(wù)
SC_HANDLE hSS = OpenService(
hSCM,
szName,
SERVICE_ALL_ACCESS
);
if (!hSS)
goto END;


///先檢測(cè)服務(wù)程序是否已經(jīng)運(yùn)行
for(int i=0;i < 300; i++)
{
SERVICE_STATUS status = {0};
if(!QueryServiceStatus(hSS, &status))
goto END;

iState = status.dwCurrentState;
if(status.dwCurrentState == SERVICE_RUNNING)
break;

if (status.dwCurrentState == SERVICE_STOPPED)
{
goto END;
}
if (status.dwCurrentState == SERVICE_START_PENDING
|| status.dwCurrentState == SERVICE_STOP_PENDING)
{
Sleep(10);
continue;
}
}

SERVICE_STATUS status = {0};
if(!ControlService(hSS,SERVICE_CONTROL_STOP,&status))
goto END;


for(int i=0;i < 300; i++)
{

if(!QueryServiceStatus(hSS, &status))
goto END;

iState = status.dwCurrentState;
if(status.dwCurrentState == SERVICE_STOPPED)
break;

if (status.dwCurrentState == SERVICE_STOP_PENDING)
{
Sleep(10);
continue;
}
}


END:
if(bDelService && hSS)
{
if(!DeleteService(hSS))
{

}
}
if(hSS)
CloseServiceHandle(hSS);
if (hSCM)
CloseServiceHandle(hSCM);

return iState;

}

5 編寫windows服務(wù)程序的功能代碼
事實(shí)上,前面4部介紹的函數(shù)不一定要出現(xiàn)在我們的服務(wù)應(yīng)用程序代碼當(dāng)中,我們可以使用控制臺(tái)命令sc來實(shí)現(xiàn)控制服務(wù)的基本操作,服務(wù)程序的功能代碼才是我們關(guān)注的核心,把一個(gè)普通的exe程序改成服務(wù)程序,我們只需要在main函數(shù)中調(diào)用windows指定的service api StartServiceCtrlDispatcher,該函數(shù)指定一個(gè)windows指定的函數(shù)指針,我們把它實(shí)現(xiàn)為ServiceMain,如代碼:

SERVICE_TABLE_ENTRY sTable[2] = {0};
sTable[0].lpServiceName = (LPSTR)szName; ///該參數(shù)被忽略,可以為空字符
sTable[0].lpServiceProc = (LPSERVICE_MAIN_FUNCTION)ServiceMain;
sTable[1].lpServiceName = NULL;
sTable[1].lpServiceProc = NULL;
if(!StartServiceCtrlDispatcher((SERVICE_TABLE_ENTRY*)sTable))
err = GetLastError();

ServiceMain才是我們程序功能代碼真正實(shí)現(xiàn)的地方,這里簡(jiǎn)單起見,我們把該服務(wù)程序的功能寫成不斷循環(huán)寫文件,
ServiceMain的函數(shù)原形和我們實(shí)現(xiàn)的代碼如下:
///StartServiceCtrlDispatcher制定的回調(diào)函數(shù)
void WINAPI ServiceMain(DWORD dwAgrc, LPSTR lpszAgrv)
{
g_statusHandle = RegisterServiceCtrlHandler(g_serviceNmae, (LPHANDLER_FUNCTION)Handler);
if(!g_statusHandle)
return;

SERVICE_STATUS status = {0};
status.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
status.dwCurrentState = SERVICE_RUNNING;
status.dwControlsAccepted = SERVICE_ACCEPT_STOP;
if(!SetServiceStatus(g_statusHandle,&status))
goto END;

while (!g_bStop)
{
FILE* pFile = fopen("d://s.service","ab+");
const char* str = "this is service test/r/n";
fwrite(str,1,sizeof("this is service test/r/n"),pFile);
fflush(pFile);
fclose(pFile);
Sleep(10000);
}

END:
status.dwCurrentState = SERVICE_STOPPED;
SetServiceStatus(g_statusHandle,&status);
}

在ServiceMain函數(shù)開始,我們立即調(diào)用了RegisterServiceCtrlHandler并指定了一個(gè)Handler函數(shù)指針,這其實(shí)是給定了外部與我們服務(wù)程序通信的方式,Handler函數(shù)就是接收外部消息的的處理函數(shù),我們前面提過的ControlService函數(shù)發(fā)出的消息就會(huì)在這里被接收和處理,SetServiceStatus就是用來設(shè)置服務(wù)管理控制器界面的服務(wù)狀態(tài)的函數(shù)。
void WINAPI Handler(DWORD fdwControl)
{

const char* szName = g_serviceNmae;

SERVICE_STATUS status = {0};
switch(fdwControl)
{
case SERVICE_CONTROL_STOP:
{
g_bStop = true;
status.dwCurrentState = SERVICE_STOPPED;
break;
}
case SERVICE_CONTROL_PAUSE:
status.dwCurrentState = SERVICE_PAUSED;
break;
case SERVICE_CONTROL_CONTINUE:
{
g_bStop= false;
status.dwCurrentState = SERVICE_RUNNING;
break;
}
case SERVICE_CONTROL_INTERROGATE:
break;
default:
break;
}

if(!SetServiceStatus(g_statusHandle,&status))
return;
}

好了,編寫windows服務(wù)程序的基本步驟入門就是這樣子了,下面給出main函數(shù)的代碼
#include 
#include

static char g_serviceNmae[1024] = "mySampleService";
static SERVICE_STATUS_HANDLE g_statusHandle = NULL;
static bool g_bStop = false;
int main(char argc, char** argv)
{
if(argc >= 3)
{
memset(g_serviceNmae,0,sizeof(char)*1024);
strcpy(g_serviceNmae, argv[2]);
}
const char* szName = g_serviceNmae;
DWORD err = 0;
if(argc > 1){
if(strcmp(argv[1],"-install")==0)
{
if(installServices(szName)==-1)
{
err = GetLastError();
}
else
{
if(ServiceStart(szName)==-1)
err = GetLastError();
}
}
else if(strcmp(argv[1],"-delete")==0)
{
if(ServiceStop(szName,true)==-1)
err = GetLastError();

}
else if(strcmp(argv[1],"-start")==0)
{
if(ServiceStart(szName)==-1)
err = GetLastError();
}
else if(strcmp(argv[1],"-stop")==0)
{
if(ServiceStop(szName)==-1)
err = GetLastError();
}
}

else
{
for (int i=0;i<100;i++)
{
Sleep(50);
}

SERVICE_TABLE_ENTRY sTable[2] = {0};
sTable[0].lpServiceName = (LPSTR)szName; ///該參數(shù)被忽略,可以為空字符
sTable[0].lpServiceProc = (LPSERVICE_MAIN_FUNCTION)ServiceMain;
sTable[1].lpServiceName = NULL;
sTable[1].lpServiceProc = NULL;
if(!StartServiceCtrlDispatcher((SERVICE_TABLE_ENTRY*)sTable))
err = GetLastError();
}

return 0;
}

原文地址:http://blog.csdn.net/xxq123321/article/details/6212252

posted on 2013-12-17 17:10 天道酬勤 閱讀(455) 評(píng)論(0)  編輯 收藏 引用 所屬分類: windows編程


只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。
網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問   Chat2DB   管理


青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            99综合在线| 午夜电影亚洲| 欧美xart系列高清| 中文精品一区二区三区| 在线视频欧美一区| 黄色成人精品网站| 99re在线精品| 一区在线观看| 在线亚洲伦理| 亚洲精品网站在线播放gif| 亚洲免费一在线| 亚洲欧洲一级| 小黄鸭精品aⅴ导航网站入口| 亚洲日韩中文字幕在线播放| 亚洲午夜精品福利| 亚洲激情欧美| 久久精品国产69国产精品亚洲| 欧美寡妇偷汉性猛交| 欧美区在线观看| 久久亚洲综合网| 国产精品久久9| 亚洲国产欧美日韩| 国产三级欧美三级| 99v久久综合狠狠综合久久| 依依成人综合视频| 亚洲欧美怡红院| 亚洲综合电影一区二区三区| 奶水喷射视频一区| 老鸭窝毛片一区二区三区| 国产精品久久久久影院色老大| 欧美jizz19性欧美| 国产中文一区二区| 亚洲欧美日韩爽爽影院| 亚洲午夜免费视频| 欧美激情综合亚洲一二区| 久久五月天婷婷| 国产日韩欧美高清免费| 亚洲午夜女主播在线直播| 牛牛精品成人免费视频| 欧美伊人久久久久久久久影院| 欧美顶级少妇做爰| 欧美成人综合在线| 在线看一区二区| 欧美在线视频一区二区三区| 性欧美video另类hd性玩具| 欧美视频中文在线看| 日韩香蕉视频| 中文日韩欧美| 国产精品电影观看| 亚洲午夜在线观看| 亚洲欧美在线aaa| 国产精品爽黄69| 亚洲一区欧美激情| 久久av一区二区三区| 国产噜噜噜噜噜久久久久久久久| 亚洲午夜激情网站| 久久成人在线| 狠狠干狠狠久久| 久久免费视频在线| 欧美激情自拍| 中国成人黄色视屏| 国产精品青草综合久久久久99| 亚洲一区二区三区四区五区午夜| 一本色道久久综合| 国产精品久久久久国产a级| 亚洲午夜成aⅴ人片| 久久久www成人免费精品| 狠狠干综合网| 欧美激情视频在线播放| 99精品视频一区二区三区| 午夜精品亚洲一区二区三区嫩草| 国产精品免费观看在线| 欧美一区永久视频免费观看| 欧美aa在线视频| 一区二区三区欧美在线| 国产精品自拍一区| 久久久免费观看视频| 亚洲日本电影| 欧美在线高清| 91久久国产精品91久久性色| 欧美日韩一区不卡| 性欧美xxxx大乳国产app| 欧美成人精品在线播放| 在线中文字幕日韩| 国产亚洲一区二区三区在线观看 | 一区二区日韩免费看| 欧美人与性禽动交情品 | 精品不卡一区| 欧美精品激情| 午夜视频一区二区| 欧美激情一区二区三区高清视频| 一区二区三区免费在线观看| 国产日韩一区欧美| 欧美精品少妇一区二区三区| 午夜精品一区二区三区在线| 亚洲电影网站| 久久福利一区| 一本色道久久综合一区| 国产拍揄自揄精品视频麻豆| 欧美aⅴ99久久黑人专区| 亚洲一区在线直播| 欧美激情一区二区三区成人| 欧美在线关看| 亚洲香蕉网站| 欧美日韩国产天堂| 欧美一区二区三区视频在线| 欧美激情第8页| 欧美中日韩免费视频| 日韩一区二区精品葵司在线| 国产一区视频网站| 国产精品不卡在线| 欧美激情久久久久久| 午夜伦理片一区| 日韩系列在线| 亚洲精品1区2区| 麻豆精品91| 久久精品日韩欧美| 亚洲男人av电影| 洋洋av久久久久久久一区| 亚洲国产成人91精品| 国产精品一区二区三区久久| 欧美日韩视频专区在线播放 | 免费在线观看精品| 欧美在线一二三四区| 亚洲天堂av综合网| 一区二区av在线| 亚洲精品社区| 亚洲黄网站黄| 亚洲国产影院| 亚洲国产裸拍裸体视频在线观看乱了| 久久一区免费| 美女视频黄a大片欧美| 久久久久青草大香线综合精品| 性色av一区二区三区| 亚洲欧美综合网| 欧美一区二区三区四区视频| 午夜伦理片一区| 欧美一区二区三区男人的天堂| 亚洲综合色噜噜狠狠| 亚洲影院在线观看| 午夜天堂精品久久久久| 欧美中文字幕精品| 久久久久青草大香线综合精品| 久久国产精品高清| 久久精品人人做人人爽| 久久精品视频在线| 久久综合激情| 亚洲福利国产| 亚洲久色影视| 亚洲网友自拍| 欧美一区二区三区久久精品| 久久99在线观看| 久久久免费观看视频| 老牛嫩草一区二区三区日本| 免费欧美日韩| 欧美日韩国产黄| 国产精品入口尤物| 国产综合色精品一区二区三区| 在线欧美日韩国产| 99热精品在线| 欧美一区二区三区在线视频 | 欧美xart系列在线观看| 欧美精品入口| 国产精品一区二区女厕厕| 黄色免费成人| 亚洲精品一区在线| 亚洲色图在线视频| 久久精品亚洲一区二区| 欧美电影电视剧在线观看| 日韩一二三区视频| 欧美一区影院| 欧美日韩爆操| 国模精品一区二区三区| 亚洲另类黄色| 久久精品九九| 日韩视频专区| 亚洲高清不卡一区| 夜夜嗨网站十八久久| 久久国产加勒比精品无码| 欧美大尺度在线观看| 国产精品一卡| 亚洲另类自拍| 久久久午夜精品| 9久re热视频在线精品| 久久久久亚洲综合| 亚洲高清视频在线观看| 亚洲午夜国产成人av电影男同| 久久久噜噜噜久久久| 国产精品久久久久久久电影| …久久精品99久久香蕉国产| 亚洲一区久久久| 亚洲大片精品永久免费| 亚洲欧美日韩天堂| 欧美日本韩国在线| 一区二区在线视频播放| 午夜国产精品视频免费体验区| 欧美激情一级片一区二区| 先锋资源久久| 国产精品豆花视频| 亚洲精品一区二区三区蜜桃久|