溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

怎么用C#實(shí)現(xiàn)Windows后臺服務(wù)

發(fā)布時間:2021-07-16 08:15:46 來源:億速云 閱讀:229 作者:chen 欄目:編程語言

這篇文章主要講解了“怎么用C#實(shí)現(xiàn)Windows后臺服務(wù)”,文中的講解內(nèi)容簡單清晰,易于學(xué)習(xí)與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學(xué)習(xí)“怎么用C#實(shí)現(xiàn)Windows后臺服務(wù)”吧!

C#實(shí)現(xiàn)Windows后臺服務(wù)實(shí)例之前要明白的一些概念:所謂Windows后臺服務(wù),即后臺自動運(yùn)行的程序,一般隨操作系統(tǒng)啟動而啟動,在我的電腦 服務(wù)后應(yīng)用程序 服務(wù)里面能看到當(dāng)前電腦的服務(wù).一般而言,程序上用VC、C++寫Windows服務(wù),但是我對這些語言不是很熟,一般編程用C#較多,所以就用C#語言寫了一個Windows服務(wù).

C#實(shí)現(xiàn)Windows后臺服務(wù)實(shí)例其實(shí)需求是這樣的,做那個報價系統(tǒng)的時候加入了發(fā)短信的功能,訂單處理完即將發(fā)貨的時候要發(fā)送短信都客戶手機(jī)上,公司內(nèi)部員工處理訂單超時要自動發(fā)短信,群發(fā)產(chǎn)品促銷信息到客戶手機(jī)上等,還有定時發(fā)送短信的需求,所以***面決定把發(fā)短信的模塊獨(dú)立出來,以后還有什么功能方便一起調(diào)用,而最終選擇了采用Windows后臺服務(wù).

C#實(shí)現(xiàn)Windows后臺服務(wù)實(shí)例其實(shí)Windows服務(wù)并不好做到通用,它并不能在用戶的界面顯示一些什么信息等,它只是在后臺默默的處理一些事情,起著輔助的作用.那如何實(shí)現(xiàn)發(fā)送段信通用調(diào)用的接口呢?它們之間的信息又是如何來交互呢?數(shù)據(jù)庫!對,就是它存儲數(shù)據(jù)信息的.而數(shù)據(jù)庫都能很方便的訪問操作.把發(fā)送短信的后臺服務(wù)定時去訪問一個數(shù)據(jù)庫,而另外任何要發(fā)送短信的地方也訪問數(shù)據(jù)庫,并插入一條要發(fā)送的短信到表里面,稍后Windows后臺服務(wù)訪問該表將此短信發(fā)送出去.這可能是一個比較蠢的方法,但實(shí)現(xiàn)起來較簡單.

C#實(shí)現(xiàn)Windows后臺服務(wù)實(shí)例首先,由于它是要安裝的,所以它運(yùn)行的時候就需要一個安裝類Installer將服務(wù)安裝到計算機(jī),新建一個后臺服務(wù)安裝類繼承自Installer,安裝初始化的時候是以容器進(jìn)行安裝的,所以還要建立ServiceProcessInstaller和ServiceInstaller服務(wù)信息組件添加到容器安裝,在Installer類增加如下代碼:

private System.ComponentModel.IContainer components = null;  private System.ServiceProcess.ServiceProcessInstaller spInstaller;  private System.ServiceProcess.ServiceInstaller sInstaller;  private void InitializeComponent()  {  components = new System.ComponentModel.Container();   // 創(chuàng)建ServiceProcessInstaller對象和ServiceInstaller對象  this.spInstaller = new System.ServiceProcess.ServiceProcessInstaller();  this.sInstaller = new System.ServiceProcess.ServiceInstaller();   // 設(shè)定ServiceProcessInstaller對象的帳號、用戶名和密碼等信息  this.spInstaller.Account = System.ServiceProcess.ServiceAccount.LocalSystem;  this.spInstaller.Username = null;  this.spInstaller.Password = null;   // 設(shè)定服務(wù)名稱  this.sInstaller.ServiceName = "SendMessage";  sInstaller.DisplayName = "發(fā)送短信服務(wù)";  sInstaller.Description = "一個定時發(fā)送短信的服務(wù)";   // 設(shè)定服務(wù)的啟動方式  this.sInstaller.StartType = System.ServiceProcess.ServiceStartMode.Automatic;   this.Installers.AddRange(new System.Configuration.Install.Installer[] { this.spInstaller, this.sInstaller });  }

C#實(shí)現(xiàn)Windows后臺服務(wù)實(shí)例再添加一個服務(wù)類繼承自ServiceBase,我們可以重寫基類的OnStart、OnPause、OnStop、OnContinue等方法來實(shí)現(xiàn)我們需要的功能并設(shè)置指定一些屬性.由于是定事發(fā)送短信的服務(wù),自然少不了Windows記時器,在OnStart事件里我們寫入服務(wù)日志,并初始化記時器.

private System.Timers.Timer time;  private static readonly string CurrentPath = Application.StartupPath + "\\";  protected override void OnStart(string[] args)  {  string path = CurrentPath + "Log\\start-stop.log";  FileStream fs = new FileStream(path, FileMode.Append, FileAccess.Write);  StreamWriter sw = new StreamWriter(fs);  sw.WriteLine("The Service is Starting On " + DateTime.Now.ToString());  sw.Flush();  sw.Close();  fs.Close();   time = new System.Timers.Timer(1000 * Convert.ToInt32(GetSettings("TimeSpan")));  time.Enabled = true;  time.Elapsed += this.TimeOut;  time.Start();  }

C#實(shí)現(xiàn)Windows后臺服務(wù)實(shí)例實(shí)例化記時器類啟動后,將在指定時間間隔觸發(fā)Elapsed指定事件,如上GetSettings為讀取我App.config文件里一個配置節(jié)點(diǎn)(值為30)的方法,所以上面將會每隔30秒調(diào)用TimeOut方法.而改方法就是我們發(fā)短信的具體操作.代碼如下:

private void TimeOut(object sender, EventArgs e)  {  try {  if (GetSettings("Enabled").ToLower() == "true")  {  SqlConnection con = new SqlConnection(GetSettings("ConnString"));  SqlCommand cmd = new SqlCommand("select [sysid],[admin_inner_code],[user_inner_code],[phone],[message],[sendtime] from [tbl_note_outbox]", con);  con.Open();  SqlDataReader rdr = cmd.ExecuteReader();  while (rdr.Read())  {  string phone = rdr["phone"].ToString();  string message = rdr["message"].ToString();  string sendtime = rdr["sendtime"].ToString();  System.Text.Encoding encoder = System.Text.Encoding.GetEncoding("GB2312");  string url = string.Format("http://211.155.23.205/isapi.dll?SendSms&AgentID={0}&PassWord={1}&phone={2}&msg={3}&sendtime={4}", GetSettings("AgentID"), GetSettings("PassWord"), phone,System.Web.HttpUtility.UrlEncode( message,encoder), sendtime);  System.Net.WebClient wClient = new System.Net.WebClient();  string msg = System.Text.Encoding.Default.GetString(wClient.DownloadData(url));  wClient.Dispose();   //刪除已經(jīng)發(fā)送成功的,并保存發(fā)送記錄  if (msg == "發(fā)送成功")  {  DateTime dtsend = sendtime == "0" ? DateTime.Now : DateTime.ParseExact(sendtime, "yyyyMMddHHmmss", null);  string sql = string.Format("delete from [tbl_note_outbox] where [sysid]={0} INSERT INTO [tbl_note_log] ([admin_inner_code],[user_inner_code],[status],[phone],[message],[sendtime]) VALUES('{1}','{2}','{3}','{4}','{5}','{6}')", rdr["sysid"], rdr["admin_inner_code"], rdr["user_inner_code"], msg, phone, message, dtsend);  SqlConnection conn = new SqlConnection(GetSettings("ConnString"));  SqlCommand delete = new SqlCommand(sql, conn);  conn.Open();  delete.ExecuteNonQuery();  conn.Close();  delete.Dispose();  }   }  rdr.Close();  con.Close();  cmd.Dispose();  }  }  catch (Exception ex)  {  string errorPath = CurrentPath + "Log\\error.log";  if (!File.Exists(errorPath))  {  FileStream create = File.Create(errorPath);  create.Close();  }  FileStream fs = new FileStream(errorPath, FileMode.Append, FileAccess.Write);  StreamWriter sw = new StreamWriter(fs);  sw.WriteLine("Exception: " +ex.Message+" --"+ DateTime.Now.ToString());  sw.Flush();  sw.Close();  fs.Close();  }   }

C#實(shí)現(xiàn)Windows后臺服務(wù)實(shí)例上面我們使用try、catch訪問數(shù)據(jù)庫,并記錄錯誤異常信息. 發(fā)送短信是使用發(fā)送一個Web請求發(fā)送出去的,要注意請求url字符串的編碼類型,要與請求頁面編碼一致,不然會出現(xiàn)亂碼.上面我們請求的是智網(wǎng)通集團(tuán)短信(網(wǎng)址:http://www.09168.net/)的Web接口,通過訪問他的網(wǎng)站來實(shí)現(xiàn)發(fā)短信,當(dāng)然還要傳遞一些用戶名、密碼、手機(jī)號碼和要發(fā)送的短信息等參數(shù).他的收費(fèi)平均大概為7分/條的樣子,其實(shí)我原本不想用發(fā)送Web請求的這樣方式來發(fā)送短信的,它本身提供了調(diào)用它發(fā)送短信的DLL,而且還有vc、delphi調(diào)用的Demo,但是沒有用C#調(diào)用的例子,我剛開始試著用非托管動態(tài)鏈接庫他提供的DLL,不知方法調(diào)用那里出錯了一直都沒能成功發(fā)送出短信,所以后來就用了他的Web方式接口了.他頁面直接返回發(fā)送短信的狀態(tài)信息.返回發(fā)送成功則短信發(fā)送成功,成功后我再將此條信息從要發(fā)送短信表里刪除并保存在發(fā)送記錄表里面,以備日后方便查詢.其實(shí)登陸他的官網(wǎng)進(jìn)入后臺也能方便的查詢,如下圖.

怎么用C#實(shí)現(xiàn)Windows后臺服務(wù)

C#實(shí)現(xiàn)Windows后臺服務(wù)實(shí)例發(fā)送短信服務(wù)的代碼基本上搞定了,就看怎么在服務(wù)器上安裝部署了.C#寫的Windows后臺服務(wù)不能直接安裝,需要借助.NET Framework里面的InstallUtil.exe安裝工具安裝,我們可以做成一個執(zhí)行CMD命令的文件BAT文件來安裝啟動它,命令如下:

%windir%\Microsoft.NET\  Framework\v2.0.50727\  InstallUtil.exe %CD%\  SendMessage.exe  net start SendMessage

怎么用C#實(shí)現(xiàn)Windows后臺服務(wù)

安裝完成以后,我們可以在我的電腦管理服務(wù)里面看到才安裝上的后臺服務(wù).

怎么用C#實(shí)現(xiàn)Windows后臺服務(wù)

經(jīng)測試,采用定時訪問數(shù)據(jù)庫發(fā)送短信的服務(wù)并不是很耗資源,剛啟動的時候只占用內(nèi)存為7、8M左右,經(jīng)過在服務(wù)器上連續(xù)運(yùn)行幾天不關(guān)閉占用的內(nèi)存也只升到15M左右,運(yùn)行比較穩(wěn)定,這里提供一個短信二次開發(fā)接口說明,有興趣的朋友可以去下載看下.

智網(wǎng)動力集團(tuán)短信二次開發(fā)說明文檔示例

特別申明:本文及內(nèi)容如非特別注明,均為本人Jonllen原創(chuàng),版權(quán)均歸原作者個人所有,轉(zhuǎn)載必須保留此段聲明,且在文章頁面明顯位置給出原文連接,否則保留追究法律責(zé)任的權(quán)利。

感謝各位的閱讀,以上就是“怎么用C#實(shí)現(xiàn)Windows后臺服務(wù)”的內(nèi)容了,經(jīng)過本文的學(xué)習(xí)后,相信大家對怎么用C#實(shí)現(xiàn)Windows后臺服務(wù)這一問題有了更深刻的體會,具體使用情況還需要大家實(shí)踐驗(yàn)證。這里是億速云,小編將為大家推送更多相關(guān)知識點(diǎn)的文章,歡迎關(guān)注!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI