windows Service 之調試過程(附加到進程里調試,而且啟動時間不能超過30秒)


         最近第一次用C#寫了一個windows service ,其實實現的內容比較簡單。就是啟動remoting 連接,但是調試相對初次寫windws service 的我來說,比較煩。沒有經驗,而且沒辦法像調試其他windows 程序一樣設置斷點,無法看到運行過程。經過查看一些相關資料后,有了一點點調試的心得。特此留筆,以待今后使用。
 
相關源碼:

static void Main()
        {
            ServiceBase[] ServicesToRun;

            // 同一進程中可以運行多個用戶服務。若要將
            // 另一個服務添加到此進程中,請更改下行以
            // 創建另一個服務對象。例如,
            //
            //   ServicesToRun = new ServiceBase[] {new Service1(), new MySecondUserService()};
            //
            ServicesToRun = new ServiceBase[] { new TeamWorldService() };

            ServiceBase.Run(ServicesToRun);
            //TeamWorldService obj = new TeamWorldService();
            //obj.OnStart();
        }



TeamWorldService :

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.ServiceProcess;
using System.Text;
using System.IO;
using Tribal.TeamWorld.API;
using Tribal.BaseClasses;
using Tribal.TeamWorld.Remoting;
using Tribal.TeamWorld.Implementation;

namespace Tribal.TeamWorld.Service
{
    partial class TeamWorldService : ServiceBase
    {
        private RemotingInterface _remotingInterface = null;
        private MainController _mainController = null;
        public TeamWorldService()
        {
            InitializeComponent();//
            
        }

        protected override  void OnStart(string[] args)
        {
            this.AddTextLine("Starting server   ( " + DateTime.Now.ToString() + " )");

            try
            {
                this.AddTextLine("Initializing MainController  ");
                this._mainController = MainController.GetInstance();
            }
            catch (Exception ex)
            {
                this.PrintExceptions(ex);
            }

            if (this._mainController != null)
            {
                this.AddTextLine("Connecting userinterface to LogController  ");
            }

            try
            {
                this.AddTextLine("Starting MainController");
                this._mainController.Start();
            }
            catch (Exception exc)
            {
                this.PrintExceptions(exc);
            }

            try
            {
                this.AddTextLine("Starting .NET RemotingInterface");
                this._remotingInterface = new RemotingInterface();
                this._remotingInterface.StartServing();
            }
            catch (Exception exc)
            {
                this.PrintExceptions(exc);
            }
        }

        protected override void OnStop()
        {
            
            this._remotingInterface.StopServing();
            this._mainController.Stop();
            this.AddTextLine("End .NET RemotingInterface");
            
        }

        private void PrintExceptions(Exception exc)
        {
            Exception current = exc;
            while (current != null)
            {
                this.AddTextLine(current.Message);
                this.AddTextLine(current.StackTrace);

                current = current.InnerException;
            }
        }


        private void AddTextLine(string line)
        {
            try
            {
                FileStream fs = new FileStream(@"C:\TeamWorldServiceLog.txt", FileMode.OpenOrCreate, FileAccess.Write);

                StreamWriter m_streamWriter = new StreamWriter(fs);

                m_streamWriter.BaseStream.Seek(0, SeekOrigin.End);

                m_streamWriter.WriteLine(line+ "\r\n");

                m_streamWriter.Flush();

                m_streamWriter.Close();

                fs.Close();
            }
            catch (Exception ex)
            { 
                
            }
        }
    }
}


方法1:寫日志
        是最傳統的調試windows service方法,也是大家在調試service 比較管用的方式,但是,調試起來還是不太明朗。你要在你認為可能出現錯誤的地方全部添加寫日志的方法。我上面的代碼就采用了AddTextLine 函數實現的這種方法。

方法2:附加進程
        附加進程的方法可以像調試正常的widows程序一樣,設置斷點進行單步調試。但是,我必須在安裝啟動服務后,才可以進行附加此服務進程,可在附加的同時OnStart 函數已經執行完畢,所以對Onstart 無法調試。但是我可以通過設置啟動服務延時來加載調試。
        步驟如下:
                     1,設置啟動服務延時,
                           

復制代碼
private System.Timers.Timer timerDelay;

        protected override void OnStart(string[] args)
        {
            try
            {
                
                ///delay start the SynData 30seconds
                timerDelay = new System.Timers.Timer(30000);   
                timerDelay.Elapsed += new System.Timers.ElapsedEventHandler(timerDelay_Elapsed);
                timerDelay.Start();
            }
            catch (Exception ex)
            {
                this.PrintExceptions(ex);
            }
        }

        void timerDelay_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            timerDelay.Enabled = false;
            timerDelay.Close();
            //你要加的代碼
            //.To do ..
        }
復制代碼

                      注意:正常服務的啟動時間為30秒左右,當服務啟動時間超過30秒會報錯!,所以不要在OnStart中做過多的操作,也可以用這種延時的方法啟動服務,以防在啟動服務時超時。
                     2、首先要對服務進行安裝,然后啟動服務。
                     3、打開vs2005  調試—>附加到進程,選擇你的服務進程(如果找不到可以勾選 顯示所有用戶的進程),就可以了。
                        進程.jpg
方法3:
      我認為是這次調試對我幫助最大。
      在Main 函數中,注釋掉原有自動生成的代碼,注意紅字部分是要根據自己的服務名字來手工添加的
             // ServiceBase[] ServicesToRun;

            // 同一進程中可以運行多個用戶服務。若要將
            
// 另一個服務添加到此進程中,請更改下行以
            
// 創建另一個服務對象。例如,
            
//
            //   ServicesToRun = new ServiceBase[] {new Service1(), new MySecondUserService()};
            
//
            //ServicesToRun 
= new ServiceBase[] { new TeamWorldService() };

            //ServiceBase.Run(ServicesToRun);
            //******************************************
            TeamWorldService obj = new TeamWorldService();
            obj.OnStart();

            //******************************************
      然后把 protected override  void OnStart(string[] args) 改為 public void OnStart()。
      ,設置你的斷點,按 F5 運行就可以調試了。

以上是自己這次調試widows service 后,得到的一些方法。以待今后繼續積累。

 

http://www.cnblogs.com/peak-weng/archive/2008/05/30/1210538.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM