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

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

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

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

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

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

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

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

if(hSS)
CloseServiceHandle(hSS);

if(hSCM)
CloseServiceHandle(hSCM);

return 0;
}

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

///打開服務
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; ///指定該服務允許被停止
status.dwServiceType=SERVICE_WIN32_OWN_PROCESS;
status.dwCurrentState=SERVICE_STOPPED;
///先檢測服務程序是否已經(jīng)運行
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ù)個數(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. 服務的停止
開啟服務后我們也會使用停止服務的功能,這里給出一個停止服務的的函數(shù)ServiceStop,可以看出該函數(shù)與ServiceSart的代碼差別不大,ServiceStop使用ControlService(WIN API )給運行中的程序發(fā)送一個SERVICE_CONTROL_STOP消息,運行中的程序收到該消息后便退出。就像你停止了apapche服務后,httpd.exe收到SERVICE_CONTROL_STOP消息并退出進程。該函數(shù)就像你在服務控制管理器中選中某一服務項后右鍵停止效果。ServiceStop函數(shù)實現(xiàn)了停止服務和刪除服務的功能,所以我們在下一步介紹服務的刪除給出代碼。

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

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


///先檢測服務程序是否已經(jīng)運行
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服務程序的功能代碼
事實上,前面4部介紹的函數(shù)不一定要出現(xiàn)在我們的服務應用程序代碼當中,我們可以使用控制臺命令sc來實現(xiàn)控制服務的基本操作,服務程序的功能代碼才是我們關注的核心,把一個普通的exe程序改成服務程序,我們只需要在main函數(shù)中調(diào)用windows指定的service api StartServiceCtrlDispatcher,該函數(shù)指定一個windows指定的函數(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才是我們程序功能代碼真正實現(xiàn)的地方,這里簡單起見,我們把該服務程序的功能寫成不斷循環(huán)寫文件,
ServiceMain的函數(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并指定了一個Handler函數(shù)指針,這其實是給定了外部與我們服務程序通信的方式,Handler函數(shù)就是接收外部消息的的處理函數(shù),我們前面提過的ControlService函數(shù)發(fā)出的消息就會在這里被接收和處理,SetServiceStatus就是用來設置服務管理控制器界面的服務狀態(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服務程序的基本步驟入門就是這樣子了,下面給出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 天道酬勤 閱讀(454) 評論(0)  編輯 收藏 引用 所屬分類: windows編程


只有注冊用戶登錄后才能發(fā)表評論。
網(wǎng)站導航: 博客園   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 | 国产精品一级| 一本色道久久88综合亚洲精品ⅰ| 麻豆av一区二区三区久久| 欧美综合77777色婷婷| 伊伊综合在线| 亚洲精品一二三| 99精品视频免费全部在线| 欧美性理论片在线观看片免费| 欧美日韩美女在线| 国产日韩欧美在线看| 国际精品欧美精品| 悠悠资源网亚洲青| 亚洲精品麻豆| 一区二区三区精品| 亚洲欧美国产不卡| 欧美在线视频导航| 麻豆freexxxx性91精品| 先锋影音网一区二区| 免费日韩av片| 欧美大秀在线观看| 亚洲日韩第九十九页| 日韩小视频在线观看| 久久久久久高潮国产精品视| 欧美二区在线播放| 91久久国产综合久久| 日韩午夜av电影| 亚洲欧美日韩综合国产aⅴ| 欧美成人午夜| 国产精品一区二区久久久久| 一区视频在线播放| 亚洲视频免费在线| 日韩一区二区精品视频| 亚洲精品中文字幕女同| 最新中文字幕一区二区三区| 在线视频亚洲欧美| 亚洲欧美久久久久一区二区三区| 精品69视频一区二区三区| 欧美精品一区二区三区在线播放| 国产欧美精品在线播放| 亚洲风情亚aⅴ在线发布| 中文国产亚洲喷潮| 久久女同互慰一区二区三区| 蜜月aⅴ免费一区二区三区| 午夜精品福利电影| 欧美高清hd18日本| 国产丝袜美腿一区二区三区| 亚洲精品综合精品自拍| 免费中文日韩| 亚洲欧美综合国产精品一区| 欧美国产日韩二区| 影音先锋久久久| 欧美一级视频精品观看| 日韩视频在线你懂得| 一区二区国产精品| 美女视频网站黄色亚洲| 亚洲二区精品| 久久精品导航| 中文久久精品| 欧美区在线播放| 一个人看的www久久| 欧美成人在线免费观看| 欧美影院视频| 国产人妖伪娘一区91| 伊人春色精品| 欧美96在线丨欧| 欧美一区二区视频免费观看| 国产精品av免费在线观看| 在线看片第一页欧美| 久久久青草青青国产亚洲免观| 亚洲黄色成人网| 免费亚洲一区二区| 亚洲国产免费看| 欧美伊人影院| 久久精品人人做人人综合| 国产精品丝袜白浆摸在线| 亚洲一区二区免费在线| 99国产精品国产精品毛片| 国产精品久久久久久久浪潮网站| 一区二区三区免费看| 亚洲精品欧洲| 欧美日韩在线一二三| 欧美制服丝袜| 欧美一区三区二区在线观看| 国产亚洲网站| 女女同性精品视频| 欧美日韩在线不卡一区| 亚洲特色特黄| 午夜国产精品视频| 国产综合视频| 国产亚洲欧美另类一区二区三区| 久热这里只精品99re8久| 久久亚洲高清| 日韩视频在线一区二区三区| 亚洲精品欧美极品| 黄色一区二区三区四区| 美女脱光内衣内裤视频久久影院| 老司机精品视频网站| 麻豆精品在线视频| 你懂的网址国产 欧美| 日韩一区二区精品| 亚洲图片你懂的| 国产一区二区中文| 午夜精品视频在线| 免费在线亚洲欧美| 午夜精品在线| 亚洲无人区一区| 香蕉久久夜色精品国产| 日韩午夜在线视频| 久久精品五月婷婷| 性色av香蕉一区二区| 欧美日韩国产精品一区| 欧美福利视频| 一区在线免费观看| 亚欧美中日韩视频| 亚洲欧美色一区| 欧美四级在线| 亚洲人成小说网站色在线| 激情成人中文字幕| 欧美在线免费播放| 欧美综合国产| 国产精品一二三四| 亚洲在线中文字幕| 亚洲欧美国产毛片在线| 欧美日韩精品一区二区三区四区| 欧美激情精品久久久久久免费印度| 国产一区欧美| 久久精品盗摄| 久久夜色精品国产亚洲aⅴ | 久久久欧美精品| 久久久99久久精品女同性| 国产精品资源在线观看| 亚洲一区二区三区色| 亚洲欧美国产精品桃花| 国产精品一区二区三区乱码 | 久久精品国产77777蜜臀| 久久精品国产99精品国产亚洲性色| 国产模特精品视频久久久久| 亚洲自拍偷拍网址| 久久精品视频在线看| 好看不卡的中文字幕| 久久色在线播放| 欧美成人嫩草网站| 亚洲欧洲精品一区二区精品久久久| 久久视频国产精品免费视频在线| 男人插女人欧美| 亚洲精品乱码久久久久久按摩观| 欧美女主播在线| 亚洲一区三区在线观看| 久久狠狠亚洲综合| 亚洲国产网站| 欧美日韩视频在线一区二区观看视频 | 欧美精品色综合| 99国产精品久久久久老师| 亚洲免费在线观看视频| 国产精品自在线| 欧美成人精品h版在线观看| 亚洲人午夜精品免费| 国产精品s色| 久久精品国产综合| 亚洲国产精品专区久久| 亚洲免费中文| 在线欧美福利| 国产精品v日韩精品v欧美精品网站| 午夜伦理片一区| 亚洲国产精品美女| 篠田优中文在线播放第一区| 亚洲第一区中文99精品| 国产精品wwwwww| 久久一区二区三区av| 一区二区三区四区五区精品视频 | 久久频这里精品99香蕉| 一本色道久久综合亚洲精品小说| 国产精品综合不卡av| 欧美激情黄色片| 久久精品电影| 亚洲一区二区三区中文字幕在线| 欧美高清不卡| 久久久久久久一区| 国产精品99久久久久久有的能看| 狠狠色丁香久久婷婷综合_中| 欧美日韩久久不卡| 久久免费少妇高潮久久精品99| 一区二区三区欧美视频| 亚洲大片精品永久免费| 久久久久久婷| 欧美一区二区三区在线观看视频| 日韩一区二区福利| 亚洲国产精品久久久久秋霞影院| 国产欧美一区二区精品性色| 欧美日韩在线另类| 欧美大片一区二区三区| 久久亚洲免费| 裸体一区二区| 久久久夜夜夜| 久久久久欧美|