亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

用托管C++編寫Windows服務

2019-11-17 05:27:54
字體:
來源:轉載
供稿:網友

  多年以來,只要提到編寫Windows服務,就會想到用Visual C++編寫,同時,這也是其中一件C++程序員可以做,而VB程序員不可以做的事情。以前,我們只稱其為"服務"或"NT服務",現在,它們被命名為"Windows服務",而且用VB.NET或C#也可以很輕易地編寫。

  但是,假如你想用托管C++來編寫呢?究竟,大多數有經驗的Visual C++程序員都會寫過一兩個服務,也會知道怎樣完成一個類似的工程。假設你有一個必須要一直運行以提供服務的程序,且連接著一些遠程電腦,假如不想編寫一本使用手冊,告訴客戶要記得在每次重啟電腦之后重新運行此程序,你就應該使它成為一個服務;又假設你有一個用于刪除過期數據庫記錄的便利維護工具,假如不想讓治理員每周都親手運行它一次,你就應該使它成為一個服務??雌饋硗ξ说模蔷妥屛覀冮_始吧。

  創建服務工程

  以下要做的事情非常簡單:打開Visual Studio.NET,創建一個新的工程,在Visual C++工程下,選擇Windows服務(.NET)。接下來,為這個服務取一個方便在電腦的服務列表中查找到的名字,在此為CGNotifier。向導會創建一個繼續自System::ServicePRocess::ServiceBase的類并打開設計視圖,在此,你可放入一個計時器、一個數據庫連接,或其他不可見的組件
讓我們轉到代碼視圖中看一下生成的代碼,在此有一個構造函數與一個Dispose方法,這兩個你都可以忽略,還有一對重載的方法:OnStart()和OnStop)。在OnStart()中,可編寫服務所需的代碼。服務中一個重要的范疇是使用"事件引發對象",例如System::IO::FileSystemWatcher的一個實例,一般可在OnStart()中創建這些對象,在本例中,你可為類加入事件方法,并處理在服務運行期間,由這些對象引發的事件。另有一種服務,它們對發生的事情不作反應,只在天天或每周的特定時間,執行一些特定的任務,這些服務平時通常處于休眠狀態,但因為它們的工作狀態是持續的,所以不應該停止它們,或者可以把它們放入一個循環中,在特定的時間檢查它們是否已被停止。

  OnStart()方法是服務的開始之處,并且會在執行完后返回,在此方法完成之前,服務一般不會顯示為"已啟動"。這就意味著,不能在OnStart()中放入一個經常使用的循環,或從別處直接調用的任何方法。最直接的方法是設置好一個單獨的方法,并在一個新線程中調用它,如下所示:

private:
bool stopping;
int loopsleep; //毫秒
Threading::Thread* servicethread;

protected:
//設置好服務應做的工作
void OnStart(String* args[])
{
 Threading::ThreadStart* threadStart =new Threading::ThreadStart(this,mainLoop);
 servicethread = new Threading::Thread(threadStart);
 servicethread->Start();
}
void mainLoop()
{
 loopsleep = 1000; //毫秒
 stopping = false;
 while (!stopping)
 {
  Threading::Thread::Sleep(loopsleep);
 }
}
  這個循環將會一直運行,直到服務停止,因為OnStop()設置了停止標志:

void OnStop()
{
 stopping = true;
}
  假如你增加loopsleep值,則會在停止時,增加服務的響應時間。 安裝服務

  盡管這個服務什么也不做,但你仍可對它進行安裝、啟動和停止。為簡化安裝過程,可在工程中加入一個安裝程序,這可在設計視圖中完成(假如你喜歡,可在設計視圖中打開屬性窗口,并修改ServiceName屬性;而向導會在工程名后加上WinService,這最好在添加安裝程序之前完成,否則,就需要在多處修改服務名。),鼠標右鍵單擊設計視圖,選擇添加安裝程序。這將創建一個服務安裝程序和一個服務過程安裝程序,并顯示在設計視圖中,以供你設置它們的屬性。

  假如已經閱讀了有關Windows服務的 .NET文檔,你可能會想為什么要添加一個安裝程序呢?難道不可以自動添加嗎?實際上,假如是使用VB或C#,是可以自動添加的,而C++卻不行。

  服務過程安裝程序只有一個比較讓人感愛好的屬性:服務所運行的賬戶。單擊serviceProcessInstaller1選擇它,打開其屬性窗口。默認情況下,賬戶屬性為User,這意味著在安裝服務時,將會提示輸入一個ID和密碼,而且服務將會運行于user權限下--這在服務運行于system賬戶時非常有用。通常有三個選項:LocalSystem是服務被安裝于未運行Windows 2003的電腦上時的唯一選擇;假如服務是面向Windows 2003的,那么LocalService的權限更少,因為是更好的選擇;而NetworkService答應服務驗證另一臺電腦,所以只在需要使用它(例如,一個服務加載了一個web頁),相反,在使用公共web服務時,就不需要作為NetworkService運行,因為它不需驗證遠程電腦。
而服務安裝程序中需要注重的屬性是StartType:手動、自動、禁用。在此例中為手動。

  現在,可以生成服務,并預備安裝了。打開Visual Studio命令提示符,定位到工程的Debug文件夾,輸入以下命令:

InstallUtil CGNotifier.exe
  以下是屏幕的輸出:

Microsoft (R) .NET Framework Installation utility
Version 1.1.4322.573
Copyright (C) Microsoft Corporation 1998-2002.
All rights reserved.

Exception occurred while initializing the installation:
System.IO.FileLoadException: Unverifiable image 'CGNotifier.exe'
cannot be run.
  這真是難以理解,不是嗎?在C++中編寫可驗證代碼向來都是不可能的,且非常難以實現。為什么工程向導創建了一個服務,但卻沒有提示你代碼必須為可驗證的呢?其實不必使你的服務程序產生可驗證代碼。

  打開解決方案資源治理器,找到并打開相應的 .cpp文件,你將會發現隱藏在此的一個main()函數--正是這個main()函數以一種"聰明"的方式為你調用了InstallUtil,并產生了整個的"可驗證代碼"問題。現在回到命令提示符窗口,像以下這樣安裝服務:

CGNotifier.exe -Install

  你可看到服務輕松、流暢地安裝上去了。

  為進行測試,現在打開"計算機治理",并展開"服務和應用程序"項,選擇"服務",你可看到新安裝上去的服務:右鍵單擊它選擇啟動。一旦服務啟動,切換回Visual Studio,選擇服務器資源治理器查看此服務:依次選擇視圖、服務器資源治理器,展開你的計算機名,再展開服務,你將看到一個新服務,而帶有的綠色三角形表明它正在運行。


用托管C++編寫Windows服務(圖一)

  在服務器資源治理器中右擊此服務,選擇停止。現在,請在"事件查看器"中查看事件記錄,可看到二個日志記錄:一個告訴你服務已啟動,而另一個告訴你服務已停止。假如你不想產生事件日志記錄,請在服務的設計視圖中修改AutoLog屬性為False。

  卸載服務

  假如你從Debug目錄中安裝此服務,在對它進行修改期間,并不需要卸載,把它停止,重新生成,再啟動就行了。但是,假如你想卸載它,請回到Visual Studio命令提示符窗口,定位到Debug目錄,輸入以下命令:

CGNotifier.exe -Install /u
  現在,服務就會從"服務器資源治理器"和"計算機治理"的服務列表中消失了,也許,需要刷新列表才能看到變化。 喚醒后做一些事情

  當然,以上所示的服務到目前為止并不能做任何事情,為把它變成一個"在設定時刻喚醒"的服務,第一步應在工程中加入一個配置文件,示例如下:

<configuration>
<appSettings>
<add key="runhour" value="22" />
</appSettings>
</configuration>
  另外,還需要復制帶應用程序名如app.config文件到目標工程目錄(Debug或Release):

copy app.config $(ConfigurationName)/$(TargetFileName).config
  為了讀取配置,可在OnStart()或mainLoop()中循環之前加入相應的代碼,在此傾向于盡可能地保持OnStart()為空,因此在mainLoop()中加入以下代碼:

String* sHour = Configuration::ConfigurationSettings::
AppSettings->get_Item("runhour");
int runHour = System::Int32::Parse(sHour);
bool rantoday = false;
  而循環則如下所示:

stopping = false;
while (!stopping)
{
 if (DateTime::Now.Hour == runHour && !rantoday)
 {
  //執行相應的任務
  rantoday = true;
 }
 else
  rantoday = false;
 Threading::Thread::Sleep(loopsleep);
}
  因為到了事先約定的時間,只想要上述代碼運行一次,因此,在服務執行完相應的任務之后,必須把rantoday標志設為true,只要在其他時間,都會被設為false。

  你可以在服務中查找數據庫的新記錄、或查找過期的文件并刪除它們,當然,在服務中可以做的事情遠遠不只這些。但不管要執行的任務是什么,都需要告訴其他人你做過什么,因為服務不具備一個用戶界面,所以也不能彈出一個消息框,因此,使用事件日志是一個不錯的方法。

  請在mainLoop()的循環之前加入以下代碼,以用于設置事件日志記錄:

Diagnostics::EventLog* log ;
if (! Diagnostics::EventLog::SourceExists("CGNotifierService") )
 Diagnostics::EventLog::CreateEventSource("CGNotifierService",CGNotifierLog");
 log = new Diagnostics::EventLog("CGNotifierLog");
 log->Source = "CGNotifierService";
  雖然不用同時設置日志和源代碼,但這樣做的話,消息會在服務器瀏覽器的事件日志之下,創建它們自己的節點。

用托管C++編寫Windows服務(圖二)

  為向日志中寫入,通常只需一行代碼--可把它放在"執行相應任務"的注釋之后: log->WriteEntry("服務的運行時間到了。",
Diagnostics::EventLogEntryType::Information);

  現在,我們大功告成:一個可以安裝、卸載、啟動、停止,并天天向事件日志中寫入一條信息的服務誕生了!從此以后,你將無堅不摧,用C++編寫的Windows服務可不像其他那些 .NET應用程序,它只局限于你的想像力。另外,在創建服務工程時,還要注重分清C++與VB及C#之間的細微差別。還等什么呢,趕緊動手啊!

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
精品久久久在线观看| 欧美另类交人妖| 久久久久久久成人| www.国产精品一二区| 国产在线观看一区二区三区| 成人精品一区二区三区电影免费| 欧美日韩中文在线观看| 国产精品欧美激情| 一区二区三区四区在线观看视频| 欧美激情a∨在线视频播放| 精品国产电影一区| 久久中文字幕视频| 久久理论片午夜琪琪电影网| 亚洲成人激情在线观看| 亚洲国产精品人人爽夜夜爽| 国产精品福利网站| 青青草原成人在线视频| 中文字幕日韩在线视频| 国产精国产精品| 国产suv精品一区二区| 亚洲www在线观看| 欧美成人精品不卡视频在线观看| 91精品中国老女人| 亚洲成avwww人| 亚洲人成啪啪网站| 色狠狠久久aa北条麻妃| 欧美—级a级欧美特级ar全黄| 日韩欧美精品中文字幕| 久久中国妇女中文字幕| 午夜精品久久久99热福利| 国产精品成人免费视频| 伊人久久久久久久久久久| 久久成人亚洲精品| 欧美巨大黑人极品精男| 九九热最新视频//这里只有精品| 午夜精品在线观看| 亚洲一区二区免费在线| 日韩欧美在线视频日韩欧美在线视频| 播播国产欧美激情| 国产一区二区三区在线看| 国产91精品久| 91亚洲精品久久久| 97欧美精品一区二区三区| 欧美孕妇孕交黑巨大网站| 国产亚洲精品久久久久久牛牛| 国产suv精品一区二区三区88区| 国产精品久久久久久久午夜| 国产国语videosex另类| 色婷婷成人综合| 久久久久久这里只有精品| 欧美一级片免费在线| 亚洲色图综合久久| 人人做人人澡人人爽欧美| 国产精品成人播放| 日韩电影中文字幕av| 成人免费观看49www在线观看| 91久久久久久国产精品| 欧美日韩xxx| 精品在线欧美视频| 成人网在线免费观看| 综合国产在线视频| 欧美成人中文字幕| 97在线观看视频国产| 国产精品男人爽免费视频1| 亚洲精品97久久| 亚洲精品永久免费精品| 成人h猎奇视频网站| 久久精品美女视频网站| 国产成人avxxxxx在线看| 欧美视频免费在线观看| 在线看日韩欧美| 国产精品久久久久免费a∨| 久久99热精品| 国产成人综合精品在线| 欧美日韩精品二区| 91精品国产免费久久久久久| 亚洲aⅴ男人的天堂在线观看| 国内精品久久久久久中文字幕| 久久免费视频在线| 国语自产精品视频在免费| 欧美日韩免费在线| 国产精品电影网| 91精品视频免费| 成人在线一区二区| 人体精品一二三区| 亚洲国产高清高潮精品美女| 欧美性猛交xxxx黑人| 色综合视频一区中文字幕| 久久在线观看视频| 久久97精品久久久久久久不卡| 亚洲成人黄色网址| 亚洲人成毛片在线播放| 久久九九有精品国产23| 午夜精品视频在线| 欧美日韩另类视频| 日韩中文字幕在线精品| 曰本色欧美视频在线| 中文字幕一精品亚洲无线一区| 亚洲男女自偷自拍图片另类| 最近2019年中文视频免费在线观看| 夜夜躁日日躁狠狠久久88av| 久久噜噜噜精品国产亚洲综合| 色99之美女主播在线视频| 亚洲网站在线看| 欧美日韩国产精品一区二区三区四区| 亚洲精品国产免费| 最近2019好看的中文字幕免费| 日韩精品免费在线| 日本久久亚洲电影| 精品成人乱色一区二区| 亚洲人成绝费网站色www| 国产伦精品一区二区三区精品视频| 国语自产精品视频在线看一大j8| 亚洲图片欧美日产| 97**国产露脸精品国产| 国产成人精品久久久| 欧美亚洲国产日本| 91精品国产综合久久香蕉的用户体验| 国产精品久久久久久久久久久不卡| 国产精品成人免费视频| 欧美成人黑人xx视频免费观看| 95av在线视频| 欧美丰满少妇xxxxx做受| 亚洲午夜未满十八勿入免费观看全集| 国产精品久久久久久av福利软件| 韩国19禁主播vip福利视频| 色午夜这里只有精品| 精品香蕉一区二区三区| 尤物99国产成人精品视频| 中文字幕在线日韩| 色中色综合影院手机版在线观看| 日韩美女视频在线观看| 色悠悠久久88| 一区二区三区 在线观看视| 国产精品网红福利| 国精产品一区一区三区有限在线| 久久伊人精品视频| 国产精品麻豆va在线播放| 久久久999成人| 亚洲国产成人爱av在线播放| 亚洲精品v欧美精品v日韩精品| 亚洲天堂av在线播放| 韩国精品美女www爽爽爽视频| 国产亚洲欧美另类中文| 91精品综合久久久久久五月天| 日韩成人小视频| 国产精品日韩欧美综合| 久久久久久久久久久久久久久久久久av| 姬川优奈aav一区二区| 日韩精品一区二区三区第95| 欧美极品在线播放| www.亚洲免费视频| 欧美成人免费视频| 久久久久久久久久久av| 日韩成人在线视频网站| 成人久久久久久久| 色婷婷综合久久久久| 久久在线精品视频| 欧美整片在线观看| 国产精品视频精品| 欧美电影在线观看完整版| 国产精品日韩在线播放| 日本高清视频精品| 激情懂色av一区av二区av|