版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1、C#發(fā)現(xiàn)之旅 - C#開發(fā)Windows Service程序本課程說(shuō)明了Windows Service程序的概念,并演示如何使用C#開發(fā)一個(gè)簡(jiǎn)單的Windows Service程序。C#工程名為MyWindowsService,編譯生成的文件是MyWindowsService.exe。本課程的演示代碼下載地址為Windows Service概念介紹Windows Service,也稱Windows服務(wù),是32位Windows操作系統(tǒng)中一種長(zhǎng)期運(yùn)行的后臺(tái)程序。它們長(zhǎng)期后臺(tái)運(yùn)行,沒有用戶界面,默默無(wú)聞,但它們卻是支持Windows正常運(yùn)行的幕后英雄,卻永無(wú)出頭之日。Windows服務(wù)程序?yàn)槠渌到y(tǒng)
2、模塊提供了非常重要的服務(wù),而且各個(gè)Windows服務(wù)分工明確,比如IISAdmin服務(wù)提供WEB內(nèi)容的發(fā)布功能,若IISAdmin服務(wù)不啟動(dòng),則靜態(tài)HTML頁(yè)面、ASP、ASP.NET或者WebService等等統(tǒng)統(tǒng)不行;有個(gè)名為“Print Spooler”的服務(wù)用于提供打印支持,若該服務(wù)不啟動(dòng),則任何軟件都不能進(jìn)行打印,比如Word,記事本或者報(bào)表軟件等等。Windows啟動(dòng)后在沒有用戶登錄時(shí)就會(huì)啟動(dòng)Windows服務(wù)。Windows NT和Windows2000,以及更新的版本操作系統(tǒng)能運(yùn)行Windows服務(wù),但Windows98及其前期版本是不能運(yùn)行服務(wù)的。我們打開Windows資源管
3、理器,在左邊的樹狀列表中選中“桌面-控制面板-管理工具”。 在右邊的列表中打開“服務(wù)”項(xiàng)目即可打開Windows服務(wù)管理器。 在這些服務(wù)中,有我們最熟悉的IIS Admin和World Wide Web Publishing服務(wù)了。我們雙擊一個(gè)服務(wù)項(xiàng)目即可打開服務(wù)屬性對(duì)話框。 Windows服務(wù)有一個(gè)服務(wù)名稱屬性,該屬性是服務(wù)的惟一的不可重復(fù)的名稱,我們可以在命令行中使用命令“net start 服務(wù)名稱”來(lái)啟動(dòng)服務(wù),使用“net stop 服務(wù)名稱”來(lái)停止服務(wù)。Windows服務(wù)的啟動(dòng)類型有自動(dòng),手動(dòng)和已禁用。當(dāng)啟動(dòng)類型為自動(dòng)時(shí),Window
4、s啟動(dòng)后不等用戶登錄就自動(dòng)啟動(dòng)服務(wù),當(dāng)啟動(dòng)類型為手動(dòng)時(shí),需要某個(gè)操作員登錄后點(diǎn)擊這里的“啟動(dòng)”按鈕來(lái)啟動(dòng)服務(wù),而當(dāng)啟動(dòng)類型為已禁用時(shí),Windows服務(wù)不能啟動(dòng)。該頁(yè)面中的“啟動(dòng)”按鈕用于啟動(dòng)尚未啟動(dòng)的Windows服務(wù),運(yùn)行提供服務(wù)的進(jìn)程;“停止”按鈕用于停止已經(jīng)啟動(dòng)的服務(wù),殺死服務(wù)進(jìn)程;而“暫停”按鈕用于通知服務(wù)進(jìn)程暫時(shí)停止提供服務(wù),但服務(wù)進(jìn)程依然存在;而“恢復(fù)”按鈕用于通知處于暫停模式的服務(wù)進(jìn)程重新提供服務(wù)。 我們可以查看服務(wù)屬性對(duì)話框的“登錄”頁(yè)面。 可以指定服務(wù)使用本地系統(tǒng)帳戶登錄,也可另外指
5、定其他的用戶,這里有一個(gè)允許服務(wù)和桌面交互的選項(xiàng),若選中此選項(xiàng),則Windows服務(wù)可以顯示圖形化用戶界面,比如顯示自己的窗體,顯示消息框等等。不過(guò)不建議使用該選項(xiàng),而且Windows服務(wù)運(yùn)行時(shí)不要顯示圖形化用戶界面。我們切換到“依存關(guān)系”頁(yè)面,可以看到本服務(wù)和其他服務(wù)的依存關(guān)系。 各個(gè)Windows服務(wù)之間可能存在依賴關(guān)系,比如IISADMIN服務(wù)就依賴另外一個(gè)名為RPC的Windows服務(wù),當(dāng)啟動(dòng)一個(gè)Windows服務(wù)時(shí),系統(tǒng)會(huì)啟動(dòng)該服務(wù)所依賴的其他Windows服務(wù)。例如我們?cè)O(shè)置IISADMIN服務(wù)為自動(dòng)啟動(dòng),而RPC服務(wù)為手動(dòng)啟動(dòng),則Windows啟動(dòng)后會(huì)試圖自動(dòng)啟動(dòng)IISA
6、DMIN服務(wù),結(jié)果會(huì)首先啟動(dòng)RPC服務(wù),即使RPC服務(wù)不是自動(dòng)啟動(dòng)。若RPC服務(wù)為禁止,無(wú)論如何也不能啟動(dòng),則IISADMIN服務(wù)就無(wú)法自動(dòng)啟動(dòng)了。C#編寫Windows服務(wù)的基本過(guò)程編寫Windows服務(wù)是一種比較高級(jí)的編程技術(shù),內(nèi)部使用了很多Windows操作系統(tǒng)的核心功能,但微軟.NET框架已經(jīng)很好的封裝了這些技術(shù)細(xì)節(jié),使得我們可以很方便的使用C#編寫自己的Windows服務(wù),其基本過(guò)程一般為1. 創(chuàng)建C#工程。創(chuàng)建一個(gè)EXE工程,可以是WinForm或者命令行格式的。添加對(duì)System.ServicePr
7、ocess.dll和System.Configuration.Install.dll的引用。2. 創(chuàng)建服務(wù)類。新增一個(gè)類,該類型繼承System.ServiceProcess.ServiceBase類型,在構(gòu)造函數(shù)中設(shè)置ServiceName屬性來(lái)指明該服務(wù)的名稱。然后重載它的OnStart方法來(lái)響應(yīng)啟動(dòng)服務(wù)的事件,重載OnStop方法來(lái)響應(yīng)停止服務(wù)的事件,重載OnPause方法來(lái)響應(yīng)暫停服務(wù)的事件,重載OnContinue方法來(lái)響應(yīng)恢復(fù)提供服務(wù)的事件。在重載這些方法時(shí)必須要立即返回,其中不能出現(xiàn)長(zhǎng)時(shí)間的操作,若
8、處理時(shí)間過(guò)長(zhǎng)則Windows服務(wù)管理器會(huì)覺得該Windows服務(wù)停止響應(yīng)而報(bào)錯(cuò)。為此我們可以使用一個(gè)線程來(lái)進(jìn)行實(shí)際的工作,而OnStart方法創(chuàng)建線程,OnStop方法關(guān)閉線程,OnPause方法掛起線程,而OnContinue方法來(lái)恢復(fù)運(yùn)行線程。3. 啟動(dòng)服務(wù)。在main函數(shù)中調(diào)用“System.ServiceProcess.ServiceBase.Run( 自定義服務(wù)類的實(shí)例 )”來(lái)運(yùn)行服務(wù)。比如“System.ServiceProcess.ServiceBase.Run( new MyS
9、ervice() )”,這里的MyService就是繼承自ServiceBase。4. 安裝服務(wù)。新增一個(gè)類,該類型繼承自System.Configuration.Install.Installer類型,該類型用于配合微軟.NET框架自帶的安裝命令行工具InstallUtil.exe的。我們?yōu)樵擃愋透郊覵ystem.ComponentModel.RunInstallerAttribute特性,并在它的構(gòu)造函數(shù)中使用System.ServiceProcess.ServiceInstaller對(duì)象和System.Se
10、rviceProcess.ServiceProcessInstaller對(duì)象向系統(tǒng)提供該服務(wù)的安裝信息。程序編譯后我們可以使用命令行“InstallUtil.exe EXE文件名”向Windows服務(wù)管理器注冊(cè)服務(wù),可以使用命令行“InstallUtil.exe /u EXE文件名”從Windows服務(wù)管理器中注銷服務(wù)。5. 編寫服務(wù)客戶端。這是一個(gè)根據(jù)實(shí)際情況而可選的過(guò)程,由于Windows服務(wù)是沒有用戶界面的,因此我們可以編寫一個(gè)具有用戶界面的程序來(lái)顯示和控制Win
11、dows服務(wù)提供的數(shù)據(jù),并進(jìn)行一些系統(tǒng)設(shè)置等操作。比如對(duì)于MS SQL Server,數(shù)據(jù)庫(kù)引擎是以服務(wù)的形式存在,而SQL Server企業(yè)管理器就是一個(gè)客戶端軟件。軟件功能需求現(xiàn)在我們要求使用C#和VS.NET2005開發(fā)一個(gè)軟件,該軟件功能為1. 該軟件能監(jiān)視指定目錄下的文件和子目錄的新增,修改,刪除和重命名操作,并將操作日志記錄到一個(gè)數(shù)據(jù)庫(kù)中。2. 該軟件以Windows服務(wù)的形式運(yùn)行,能監(jiān)視不同的用戶帳戶的操作記錄。3.&
12、#160; 有一個(gè)客戶端軟件能控制服務(wù),并能查看服務(wù)的保存的監(jiān)視記錄。其用戶界面為客戶端軟件還能設(shè)置服務(wù)監(jiān)視的目錄,系統(tǒng)設(shè)置對(duì)話框?yàn)檐浖O(shè)計(jì)命令行參數(shù)設(shè)計(jì)一般而言,我們將服務(wù)和客戶端分成兩個(gè)C#工程開發(fā),但這里為了方便我們只在一個(gè)工程中實(shí)現(xiàn)服務(wù)器和客戶端軟件的開發(fā)。Windows服務(wù)是不能顯示圖形化用戶界面的,但并不是說(shuō)Windows服務(wù)的軟件中不能包含顯示圖形化用戶界面的軟件模塊。我們完全可以編寫一個(gè)EXE,其中包含服務(wù)器和客戶端兩個(gè)相互獨(dú)立的軟件模塊。直接執(zhí)行EXE將以服務(wù)模式運(yùn)行,若帶有命令行參數(shù)將以客戶端模式運(yùn)行。為
13、此我們?cè)O(shè)計(jì)了如下的命令行參數(shù)命令行參數(shù)功能無(wú)任何參數(shù)以服務(wù)模式運(yùn)行,調(diào)用ServiceBase.Run函數(shù)來(lái)運(yùn)行服務(wù)。/install調(diào)用InstallUtil.exe安裝服務(wù),將EXE自己注冊(cè)到Windows服務(wù)管理器中。/uninstall調(diào)用InstallUtil.exe卸載服務(wù)。/client以客戶端模式運(yùn)行,顯示圖形用戶界面。/debug以調(diào)試模式下運(yùn)行,方便VS.NET對(duì)服務(wù)的操作過(guò)程提供調(diào)試。使用VS.NET調(diào)試服務(wù)是一個(gè)比較麻煩的事,首先我們得安裝并運(yùn)行服務(wù),然后使用VS.NET的菜單項(xiàng)目“工具-附加到進(jìn)程”的操作來(lái)附加到服務(wù)程序,然后設(shè)置斷點(diǎn)進(jìn)行調(diào)試,其中OnStart函數(shù)是
14、沒有辦法設(shè)置斷點(diǎn)調(diào)試的。為此我們專門添加一個(gè)“/debug”命令行參數(shù)使得程序不進(jìn)入服務(wù)模式,而是直接運(yùn)行提供服務(wù)內(nèi)容的功能性代碼,然后主線程休眠,但功能性代碼還在運(yùn)行,可以調(diào)試。這樣我們?cè)赩S.NET中設(shè)置斷點(diǎn)后可以直接運(yùn)行進(jìn)行調(diào)試了。這里我們?cè)O(shè)計(jì)的C#工程名稱為MyWindowsService,編譯生成的文件為MyWindowsService.exe。數(shù)據(jù)庫(kù)設(shè)計(jì)在本軟件中,數(shù)據(jù)將保存到應(yīng)用程序目錄下的一個(gè)名為FileSystemWatcher.mdb的Access2000格式的數(shù)據(jù)庫(kù)。數(shù)據(jù)庫(kù)中的表結(jié)構(gòu)為文件系統(tǒng)操作日志表 FileSystemLog,字段有字段名類型說(shuō)明Recor
15、dID文本(50)記錄編號(hào)WatchTime文本(20)記錄時(shí)間,為yyyy-MM-dd HH:mm:ss格式ObjectName文本(250)對(duì)象名稱EventStyle文本(50)事件類型該數(shù)據(jù)表中保存的數(shù)據(jù)范例為RecordIDWatchTimeObjectNameEventStyle0d4e0d9a-6826-415b-bd47-c86fbb1449b02008-10-02 15:31:27c:"aaaaaa.txtRenamed22c1df6d-4f94-488c-a705-e8024d8752132008-10-02 20:37:03d:"aa.pngRenam
16、ed27632fe8-6cbf-4a41-95ad-6ab2e82221922008-10-02 20:40:56c:"a.pdfCreated48403266-0150-44c8-8efa-169f7a68bcb42008-10-03 11:02:04c:"zzzzzz.bmpRenamed6c3b603a-f43b-415c-8122-4aa23376d5752008-10-02 11:26:57c:"SDC_2008_10_2.logChanged6fb9fad1-51f5-40b2-b05b-d0628f775a3c2008-10-02 15:31:52c
17、:"aaaaaa.txtDeleted735d74e6-1548-4d7d-9048-ab75dd1c58742008-10-02 20:31:27c:"aa.bmpRenamed7b36a079-c56c-48f7-9c6e-cf0d77b9c6c12008-10-02 11:27:12c:"SDC_2008_10_2.logChanged7c2672ac-b210-4eca-9277-2505030e72e52008-10-02 20:39:12d:"aa.pngDeleted9ab95c19-ccd0-43eb-89ec-3930ebec9a8d2
18、008-10-02 21:55:57c:"b.bmpRenamed9adb5696-fb6a-497e-b4ff-06f5da8964342008-10-02 20:39:12d:"1.pngDeleted9f4d702f-57c1-46ec-a827-701c2a15ee812008-10-02 23:59:04c:"新建文件夾Createdc163fa48-f5ea-49b1-95c9-b89f9ee622e52008-10-02 11:26:42c:"新建 文本文檔.txtCreated對(duì)于新增文件或目錄操作其EventStyle值為Cr
19、eated,對(duì)于修改為Changed,對(duì)于刪除為Deleted,對(duì)于重命名為Renamed。 系統(tǒng)設(shè)置信息表 SystemConfig,字段有字段名類型說(shuō)明ConfigName文本(50)系統(tǒng)配置名稱ConfigValue文本(250)配置數(shù)據(jù)該數(shù)據(jù)表中保存的數(shù)據(jù)的范例為ConfigNameConfigValueLogChangedTrueLogCreatedTrueLogDeletedTrueLogRenamedFalsepath0c:"*.txtpath1d:" 在這里
20、配置項(xiàng)LogChanged表示是否監(jiān)視文件內(nèi)容是否被改變事件,配置項(xiàng)LogCreated表示是否監(jiān)視新建文件或目錄事件,配置項(xiàng)LogDeleted表示是否監(jiān)視文件或目錄刪除事件,配置項(xiàng)LogRenamed表示是否監(jiān)視文件或目錄重命名事件。而path0,path1,path2等表示監(jiān)視的路徑,支持通配符。系統(tǒng)配置中可以有若干個(gè)path配置項(xiàng)。文件系統(tǒng)監(jiān)視功能設(shè)計(jì)我們可以使用System.IO.FileSystemWatcher來(lái)監(jiān)視文件系統(tǒng)的對(duì)象的修改,我們可以使用它的Path屬性來(lái)設(shè)置要監(jiān)視的文件夾,使用Filter屬性來(lái)設(shè)置文件名過(guò)濾器,然后響應(yīng)它的Changed事件來(lái)處理文件內(nèi)容修改操作,
21、響應(yīng)Created事件來(lái)處理新增文件或目錄操作,響應(yīng)Deleted事件來(lái)處理刪除文件或目錄操作,響應(yīng)Renamed事件來(lái)處理文件和目錄重命名操作。這這里我們簡(jiǎn)單是將這些事件信息保存到數(shù)據(jù)表FileSystemLog中。程序在監(jiān)視文件系統(tǒng)前會(huì)讀取系統(tǒng)配置信息表SystemConfig中讀取配置信息,根據(jù)其中的path配置項(xiàng)目創(chuàng)建若干個(gè)FileSystemWatcher對(duì)象展開監(jiān)視。我們選定服務(wù)的名稱為“MyFileSystemWatcher”??蛻舳嗽O(shè)計(jì)本軟件的客戶端具有一個(gè)圖形化用戶界面,其界面設(shè)計(jì)如下客戶端主窗體工具條:刷新 刪除記錄 系統(tǒng)配置 啟動(dòng)服務(wù)
22、0;停止服務(wù)數(shù)據(jù)列表顯示從 FileSystemLog表查詢所得的數(shù)據(jù)狀態(tài)欄此外還有一個(gè)系統(tǒng)配置對(duì)話框,用于查看和修改數(shù)據(jù)表SystemConfig中保存的系統(tǒng)配置信息。軟件說(shuō)明根據(jù)上述的軟件設(shè)計(jì),我已經(jīng)把軟件編寫完畢,現(xiàn)對(duì)該軟件結(jié)構(gòu)進(jìn)行說(shuō)明客戶端主界面 frmClient本軟件為一個(gè)C#編寫的EXE,主要包含服務(wù)端軟件模塊和客戶端軟件模塊。首先對(duì)比較好理解的具有圖形化用戶界面的客戶端模塊進(jìn)行說(shuō)明,客戶端的主界面為 這個(gè)界面主要功能是數(shù)據(jù)庫(kù)信息管理,最上面為一個(gè)工具條,中間大部分的一個(gè)ListView控件,最下面為狀態(tài)欄。對(duì)于ListView控件其內(nèi)容是分組的,因
23、此需要設(shè)計(jì)其分組信息,在VS.NET的窗體設(shè)計(jì)器中我們點(diǎn)中ListView控件,在旁邊的屬性列表中選擇Groups屬性,點(diǎn)擊旁邊的小按鈕可以彈出分組設(shè)計(jì)器。 使用這個(gè)分組編輯器我們可以很容易的設(shè)計(jì)該ListView控件的分組信息。這個(gè)窗體的加載事件處理為/ <summary>/ 服務(wù)已經(jīng)安裝標(biāo)記/ </summary>private bool bolServiceInstalled = false private void frmViewLog_Load(object sender,
24、60;EventArgs e) try System.ServiceProcess.ServiceController control = newSystem.ServiceProcess.ServiceController("MyFileSystemWatcher"); System.ServicePro
25、cess.ServiceControllerStatus status = control.Status; control.Dispose(); bolServiceInstalled = true; catch( Exception ext )
26、; lblServiceInstall.Text = "服務(wù)尚未安裝" ; myTimer.Enabled = false ; btnStartService.Enabled = false ; btnStopService.Enabled =
27、60;false ; bolServiceInstalled = false ; MessageBox.Show( this,"服務(wù)尚未安裝:" + ext.Message , "系統(tǒng)錯(cuò)誤"); this.btnRefresh_Click(null,
28、0;null);在這里我們首先創(chuàng)建一個(gè)聯(lián)系到文件監(jiān)視服務(wù)的ServiceController,調(diào)用它的Status屬性,若一切正常則表示服務(wù)已經(jīng)安裝,我們?cè)O(shè)置bolServiceInstalled的標(biāo)志變量,若發(fā)生錯(cuò)誤則服務(wù)尚未安裝,則顯示“服務(wù)尚未安裝”的提示信息。 對(duì)于工具條的“刷新列表”按鈕,其點(diǎn)擊事件處理為private void btnRefresh_Click(object sender, EventArgs e) this.Cursor = System.Windows.Forms.C
29、ursors.WaitCursor; lvwRecord.BeginUpdate(); try lvwRecord.Items.Clear(); using (System.Data.IDbCommand cmd = Util.DBConnection.CreateCommand(
30、) cmd.CommandText = "Select RecordID , ObjectName , WatchTime , EventStyle From FileSystemLog order by WatchTime"
31、60; System.Data.IDataReader reader = cmd.ExecuteReader(); while (reader.Read()
32、 ListViewItem NewItem = new ListViewItem(); NewItem.Tag = Convert.ToString(reader.GetValue(0);
33、 NewItem.Text = Convert.ToString(reader.GetValue(1); NewItem.SubItems.Add(Convert.ToString(reader.GetValue(2);
34、;string Style = Convert.ToString(reader.GetValue(3); NewItem.SubItems.Add(Style); Style = Style.Trim().ToLower();
35、160; if (Style = "created")
36、 NewItem.Group = lvwRecord.Groups0; NewItem.ImageIndex = 0;
37、 else if (Style = "changed") &
38、#160; NewItem.Group = lvwRecord.Groups1; NewItem.ImageIndex = 1;
39、160; else if (Style = "deleted")
40、160; NewItem.Group = lvwRecord.Groups2; NewItem.ImageIndex = 2;
41、60; else if (Style = "renamed")
42、60; NewItem.Group = lvwRecord.Groups3; NewItem.ImageIndex = 3;
43、0; NewItem.StateImageIndex = NewItem.ImageIndex; lvwRecord.Items.Add(Ne
44、wItem); reader.Close(); myStatus.Text = "共列出 " + lvwRecord.Items.Co
45、unt + " 個(gè)記錄" catch (Exception ext) MessageBox.Show(ext.ToString(), "系統(tǒng)錯(cuò)誤"); this.Cursor = System.Windows.Forms.Curs
46、ors.Default; lvwRecord.EndUpdate();在該按鈕事件處理中,我們查詢數(shù)據(jù)表FileSystemLog,對(duì)每一條查詢所得的數(shù)據(jù)創(chuàng)建一個(gè)ListViewItem項(xiàng)目,并根據(jù)記錄的EventStyle值設(shè)置該列表項(xiàng)目的圖標(biāo)序號(hào)和分組狀態(tài)。 工具條的“刪除記錄”按鈕用于刪除列表中選擇的項(xiàng)目,其點(diǎn)擊事件處理為private void btnDelete_Click(object sender, EventArgs e) if (lvwRecor
47、d.SelectedItems.Count > 0) using (System.Data.IDbCommand cmd = Util.DBConnection.CreateCommand() for (int
48、160;iCount = lvwRecord.Items.Count - 1; iCount >= 0; iCount-) ListViewItem item = lvwRecord.ItemsiCount; &
49、#160; if (item.Selected) cmd.Command
50、Text = "Delete From FileSystemLog Where RecordID = '" + item.Tag + "'" cmd.ExecuteNonQuery(); &
51、#160; lvwRecord.Items.Remove(item); /for /using
52、 在刷新列表中,我們將列表項(xiàng)目的Tag屬性值設(shè)置為數(shù)據(jù)庫(kù)記錄的編號(hào),在這里我們利用這個(gè)事先保存的數(shù)據(jù)庫(kù)記錄的編號(hào)拼湊出SQL語(yǔ)句然后刪除指定的記錄。 工具條的“啟動(dòng)服務(wù)”按鈕用于啟動(dòng)后臺(tái)的文件監(jiān)視服務(wù)。其點(diǎn)擊事件處理為private void btnStartService_Click(object sender, EventArgs e) if (bolServiceInstalled = false) &
53、#160; return; using (System.ServiceProcess.ServiceController control = newSystem.ServiceProcess.ServiceController("MyFileSystemWatcher") if (control.Status = System.ServicePr
54、ocess.ServiceControllerStatus.Stopped) control.Start(); 在這里我們創(chuàng)建一個(gè)ServiceController對(duì)象,若判斷出服務(wù)的狀態(tài)為停止,則調(diào)用控制器的Start方法來(lái)啟動(dòng)服務(wù),在這里Start方法內(nèi)部
55、只是通知操作系統(tǒng)啟動(dòng)指定名稱的服務(wù),它發(fā)送通知后立即返回,并不會(huì)等待服務(wù)啟動(dòng)后返回。類似的對(duì)于“停止服務(wù)”,其點(diǎn)擊事件處理為private void btnStopService_Click(object sender, EventArgs e) if (bolServiceInstalled = false) return; using (System.Ser
56、viceProcess.ServiceController control = newSystem.ServiceProcess.ServiceController("MyFileSystemWatcher") if (control.Status = System.ServiceProcess.ServiceControllerStatus.Running)
57、60; control.Stop(); 在這個(gè)處理過(guò)程中,若判斷出服務(wù)狀態(tài)為運(yùn)行中,則調(diào)用控制器的Stop方法來(lái)停止服務(wù)。在這里Stop方法內(nèi)部只是通知操作系統(tǒng)停止指定的服務(wù),它發(fā)送通知后立即返回,不會(huì)等待服務(wù)停止后返回。我們還在窗體上放置一個(gè)定時(shí)器控件,定時(shí)間隔為2秒,用于根據(jù)服務(wù)的狀態(tài)刷新工具條按鈕狀態(tài),其定時(shí)事件處理為pri
58、vate void myTimer_Tick(object sender, EventArgs e) if (bolServiceInstalled = false) return; using (System.ServiceProcess.ServiceController control = newSystem.ServiceProces
59、s.ServiceController("MyFileSystemWatcher") btnStartService.Enabled = (control.Status = System.ServiceProcess.ServiceControllerStatus.Stopped); btnStopService.Enabled = (control.Status = S
60、ystem.ServiceProcess.ServiceControllerStatus.Running); 在這里我們創(chuàng)建了一個(gè)綁定到文件系統(tǒng)監(jiān)控服務(wù)的ServiceController對(duì)象,然后根據(jù)它的Status狀態(tài)來(lái)設(shè)置“啟動(dòng)服務(wù)”和“停止服務(wù)”按鈕的可用狀態(tài)。系統(tǒng)配置對(duì)話框 dlgConfig在客戶端主窗體中點(diǎn)擊工具條的“系統(tǒng)配置”按鈕就會(huì)彈出系統(tǒng)設(shè)置對(duì)話框,該對(duì)話框的用戶界面為該對(duì)話框比較簡(jiǎn)單,就是用于顯示和修改系統(tǒng)配置信息對(duì)象MyConfig中的內(nèi)容。由于文件系統(tǒng)監(jiān)視服務(wù)只有在啟動(dòng)的時(shí)候讀取系統(tǒng)配置信息,因此對(duì)系統(tǒng)配置的任何修改都需要
61、重新啟動(dòng)服務(wù)才能生效。系統(tǒng)配置信息對(duì)象 MyConfig系統(tǒng)配置信息對(duì)象MyConfig用于讀取和修改保存在數(shù)據(jù)表SystemConfig中的系統(tǒng)配置信息。其包含的配置信息的代碼如下private bool bolLogRenamed = true;/ <summary>/ 是否記錄重命名事件/ </summary>public bool LogRenamed get return bolLogRenamed;
62、; set bolLogRenamed = value; private bool bolLogChanged = true;/ <summary>/ 是否記錄文件修改事件/ </summary>public bool LogChanged get return bolLogChanged; set bolLogChanged = value;
63、 private bool bolLogCreated = true;/ <summary>/ 是否記錄對(duì)象創(chuàng)建事件/ </summary>public bool LogCreated get return bolLogCreated; set bolLogCreated = value; private bool bolLogDeleted = true;/
64、0;<summary>/ 是否記錄對(duì)象刪除事件/ </summary>public bool LogDeleted get return bolLogDeleted; set bolLogDeleted = value; private string myWatchedPaths = null;/ <summary>/ 監(jiān)視的目錄/ </
65、summary>public string WatchedPaths get return myWatchedPaths; set myWatchedPaths = value; 它的Load方法用于從數(shù)據(jù)庫(kù)中加載配置信息,其處理過(guò)程為public void Load() myWatchedPaths = null; System.Collections.ArrayList path
66、s = new System.Collections.ArrayList(); using (System.Data.IDbCommand cmd = Util.DBConnection.CreateCommand() cmd.CommandText = "Select ConfigName , ConfigValue From SystemConfig"
67、0; System.Data.IDataReader reader = cmd.ExecuteReader(); while (reader.Read() string Name = Convert.ToString(reader.GetValue(0
68、); if (Name = null) continue;
69、 Name = Name.Trim().ToLower(); string Value = Convert.ToString(reader.GetValue(1);
70、160; if (Name.StartsWith("path") paths.Add(Value.Trim();
71、0; else if (Name = "logrenamed") bolLogRenamed = Convert.ToBoolean(Va
72、lue); else if (Name = "logchanged")
73、160; bolLogChanged = Convert.ToBoolean(Value); else if (Name = "logdeleted")
74、; bolLogDeleted = Convert.ToBoolean(Value);
75、; else if (Name = "logcreated") bolLogCreated = Convert.ToBoolean(Value);
76、160; myWatchedPaths = (string)paths.ToArray(typeof(string);在該方法中程序查詢數(shù)據(jù)表SystemConfig中的配置項(xiàng)目名稱和數(shù)據(jù),若項(xiàng)目名稱以“path”開頭則為要監(jiān)視的路徑,而配置項(xiàng)logrenamed,logchanged,logdeleted,logcreated分別表示是否監(jiān)視文件目錄重命名,修改,刪除和新建等操作。MyConfig對(duì)象還有一個(gè)
77、Save方法用于將系統(tǒng)配置信息保存到數(shù)據(jù)庫(kù)中,其處理過(guò)程為public void Save() using (System.Data.IDbCommand cmd = Util.DBConnection.CreateCommand() cmd.CommandText = "Delete From SystemConfig"
78、60; cmd.ExecuteNonQuery(); cmd.CommandText = "Insert Into SystemConfig ( ConfigName , ConfigValue ) Values( ? , ? )" ; System.Data.IDbDataParameter pName = cmd.CreateParameter();
79、; cmd.Parameters.Add( pName ); System.Data.IDbDataParameter pValue = cmd.CreateParameter(); cmd.Parameters.Add( pValue );
80、; pName.Value = "LogRenamed" pValue.Value = bolLogRenamed.ToString(); cmd.ExecuteNonQuery(); pName.Value = "LogChanged" &
81、#160; pValue.Value = bolLogChanged.ToString(); cmd.ExecuteNonQuery(); pName.Value = "LogDeleted" pValue.Value = bolLogDeleted.ToS
82、tring(); cmd.ExecuteNonQuery(); pName.Value = "LogCreated" pValue.Value = bolLogCreated.ToString(); cmd.Execute
83、NonQuery(); for (int iCount = 0; iCount < myWatchedPaths.Length; iCount+) string path = myWatchedPaths iCount ;
84、; if( path = null | path.Trim().Length = 0 ) continue ;
85、0; pName.Value = "path" + iCount ; pValue.Value = path ; cmd.ExecuteN
86、onQuery(); 在這個(gè)方法中,首先刪除數(shù)據(jù)表SystemConfig中所有的記錄,然后將所有的配置信息保存到數(shù)據(jù)表SystemConfig中。文件系統(tǒng)監(jiān)視服務(wù) MyFileSystemWatcherService類MyFileSystemWatcherService就是文件系統(tǒng)監(jiān)視服務(wù),它是從ServiceBase派生的,首先說(shuō)明一下執(zhí)行文件系統(tǒng)監(jiān)視的功能性的過(guò)程,其代碼如下/ <summary>/ 文件系統(tǒng)監(jiān)視器列表/ </su
87、mmary>private System.Collections.ArrayList myWatchers = null; / <summary>/ 開始啟動(dòng)文件系統(tǒng)監(jiān)視/ </summary>/ <returns>操作是否成功</returns>internal bool StartFileSystemWatching() myWatchers = new System.Collections.ArrayList(); &
88、#160; MyConfig.Instance.Load(); string paths = MyConfig.Instance.WatchedPaths; System.Text.StringBuilder myPathList = new StringBuilder(); if (paths != null)
89、; foreach (string path in paths) if (System.IO.Path.IsPathRooted(path) = false)
90、60; continue; string BasePath = null; &
91、#160; string Filter = null; if (System.IO.Directory.Exists(path)
92、0; BasePath = path; Filter = "*.*"
93、0; else BasePath = System.IO.Path.GetDirectoryName(path);
94、0; Filter = System.IO.Path.GetFileName(path); if (BasePath = null)
95、 continue; BasePath = BasePath.Trim();
96、0; if (BasePath.ToUpper().StartsWith(System.Windows.Forms.Application.StartupPath) / 不能監(jiān)視程序本身所在的目錄的文件系統(tǒng)更改
97、0; continue; if (System.IO.Directory.Exists(BasePath) = false)
98、 / 不能監(jiān)視不存在的目錄 continue;
99、160; if (myPathList.Length > 0) myPath
100、List.Append(""); myPathList.Append(path); System.IO.FileSystemWatcher watcher = new
101、60;System.IO.FileSystemWatcher(); watcher.Path = BasePath; watcher.Filter = Filter; watcher.EnableRais
102、ingEvents = true; watcher.IncludeSubdirectories = false; if (MyConfig.Instance.LogChanged) watcher.Changed += delegate(object sender, System.IO.FileSystemEventArgs args)
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 商標(biāo)權(quán)知識(shí)產(chǎn)權(quán)轉(zhuǎn)讓合同
- 債權(quán)轉(zhuǎn)讓合同范例
- 戶外廣告合同樣本格式模板
- 二手車輛買賣協(xié)議范本
- 2024年接送服務(wù)合同標(biāo)準(zhǔn)范本
- 股份協(xié)議書合同股份協(xié)議書2024年
- 房屋買賣代理合同范文
- 2024年離婚協(xié)議書官方范本
- 2024年購(gòu)買香蕉的買賣合同范本
- 2024年居間公司股份轉(zhuǎn)讓合同
- 小學(xué)數(shù)學(xué)西南師大六年級(jí)上冊(cè)二圓《圓》PPT
- 建設(shè)工程安全隱患排查表
- 山西省太原市2023屆高三上學(xué)期期中數(shù)學(xué)試題
- 英文工作證明Letter-of-Employment-(模版)
- 壓力式泡沫比例混合裝置安裝使用說(shuō)明書
- 高中政治課程標(biāo)準(zhǔn)解讀 匯報(bào)課件
- 整改措施及落實(shí)情況反饋表
- 基肥一生物菌肥田間肥效試驗(yàn)專題方案
- 輟學(xué)學(xué)生勸返記錄表
- 丑小鴨-完整版PPT
- 成本法與剩余法計(jì)算公式深入探析
評(píng)論
0/150
提交評(píng)論