2010-10-18 83 views
12

我將首先說我不是.NET開發人員,但已被引入到需要使用MSMQ的項目中,以便使用傳統的ASP Web應用程序可以將消息發送到處理該處理的C#Windows服務。我有將其他消息隊列與其他語言集成的經驗,但就像我之前提到的那樣,我沒有太多的.NET和Windows開發經驗,所以我們將非常感謝一些指導。如何爲MSMQ創建C#監聽器服務作爲Windows服務

這裏是我的問題...

  1. 可能有人提供了通過做一些簡單的像寫當前時間戳到日誌監聽到現有的MSMQ隊列和響應新的消息的一些基本的C#代碼文件還是發送電子郵件?

  2. 如何在Visual Studio .NET中打包此代碼以創建並安裝Windows服務? (應該是什麼類型的項目等等,我使用的是Visual C#2010 Express。)

  3. 最後,我不確定MSMQ的哪個版本和/或實現需要用於我的需求,經典的ASP。我認爲COM版本是我需要的,但我也讀過關於新的WCF版本,以及3.0和4.0之間的差異。有人可以給我指示我應該使用哪個版本?

非常感謝!

回答

3

據我所知,Visual Studio Express沒有用於服務的項目模板。這並不意味着您無法使用VSE編寫Windows服務,只是您不會有模板來啓動。

要創建服務,您只需創建一個正常的控制檯應用程序。創建將負責實際服務實現的服務類。它會是這個樣子

using System.ServiceProcess; 

namespace WindowsService1 
{ 
    public partial class Service1 : ServiceBase 
    { 
    public Service1() 
    { 
     InitializeComponent(); 
    } 

    protected override void OnStart(string[] args) 
    { 
    } 

    protected override void OnStop() 
    { 
    } 
    } 
} 

那麼該服務的啓動代碼可以進入你的服務的Main功能。

using System.ServiceProcess; 

namespace WindowsService1 
{ 
    static class Program 
    { 
    static void Main() 
    { 
     ServiceBase[] ServicesToRun; 
     ServicesToRun = new ServiceBase[] 
      { 
       new Service1() 
      }; 
     ServiceBase.Run(ServicesToRun); 
    } 
    } 
} 

這應該給你你的服務的基本框架。您需要的另一件事是添加服務的安裝程序,以便它可以作爲服務安裝。下面應該讓你開始,注意我已經注意到了這一點。

using System.ComponentModel; 
using System.Configuration.Install; 
using System.ServiceProcess; 

namespace WindowsService1 
{ 
    [RunInstaller(true)] 
    public class ProjectInstaller : Installer 
    { 
    private ServiceProcessInstaller serviceProcessInstaller1; 
    private ServiceInstaller serviceInstaller1; 

    public ProjectInstaller() 
    { 
     this.serviceProcessInstaller1 = new ServiceProcessInstaller(); 
     this.serviceInstaller1 = new ServiceInstaller(); 

     this.serviceProcessInstaller1.Password = null; 
     this.serviceProcessInstaller1.Username = null; 

     this.serviceInstaller1.ServiceName = "Service1"; 

     this.Installers.AddRange(new System.Configuration.Install.Installer[] { 
     this.serviceProcessInstaller1, 
     this.serviceInstaller1}); 
    } 
    } 
} 

鑑於上述情況,您應該有足夠的搜索範圍或要求有關服務創建的更多細節。對於MSMQ監聽器,你可以用下面的MSDN文章爲出發點

http://msdn.microsoft.com/en-us/library/ms978425.aspx

+0

偉大的示例代碼,讓我開始在Windows服務,謝謝。 – philfeyn 2010-10-18 04:28:38

+0

有沒有其他方法可以安裝服務,即使是手動安裝?將代碼和密碼硬編碼到代碼中運行服務似乎對我來說是不好的做法。 – philfeyn 2010-10-19 02:23:50

+0

@philfeyn,您可以設置ServiceProcessInstaller.Account來選擇帳戶的類型。如果它設置爲ServiceAccount.User並且用戶名/密碼設置爲空,則在安裝服務時將提示您輸入憑據。您可以使用.NET框架附帶的InstallUtil.exe手動安裝該服務。 – 2010-10-19 03:21:12

8

可以等待使用下面的代碼(您想使用名爲SomeQueue專用隊列在給定的隊列中的消息你的電腦,命名爲計算機名=> QUEUENAME = @「計算機名\私人$ \ SomeQueue」)上

public void AsyncWatchQueue(object encapsulatedQueueName) 
    { 
     Message newMessage; 
     MessageQueue queue; 

     string queueName = encapsulatedQueueName as string; 
     if (queueName == null) 
      return; 

     try 
     { 
      if (!MessageQueue.Exists(queueName)) 
       MessageQueue.Create(queueName); 
      else 
      { 
       queue = new MessageQueue(queueName); 

       if (queue.CanRead) 
        newMessage = queue.Receive(); 
      } 
      HandleNewMessage(newMessage); // Do something with the message 
     } 
     // This exception is raised when the Abort method 
     // (in the thread's instance) is called 
     catch (ThreadAbortException e) 
     { 
      //Do thread shutdown 
     } 
     finally 
     { 
      queue.Dispose(); 
     } 
    } 

注:Receove方法將阻塞,直到消息被接收到時它會刪除消息從隊列中返回並返回。

編輯:添加的代碼爲多線程部分的執行(並更名爲上述方法簽名)

線程創建代碼:

 public Thread AddWatchingThread(string QueueName) 
    { 
     Thread Watcher = 
      new Thread(new ParameterizedThreadStart(AsyncWatchQueue)); 
     Watcher.Start(QueueName); 
     // The thread instance is used to manipulate (or shutdown the thread) 
     return Watcher; 
    } 

我就注意到,這是未經測試鱈魚,它只是一個簡單的例子

+0

你確定Exists()調用會起作用嗎? http://blog.plumbersmate.eu/archive/2010/10/18/checking-if-msmq-queues-exist-is-hard-work-so-should.aspx – 2010-10-18 12:35:05

+0

@Neowizard,使用上面的Windows服務示例代碼,您的代碼屬於WindowsService1的OnStart()方法是否正確?當x.Receive()收到一條消息時,它返回哪裏?你能提供一些關於創建一個等待消息的新線程的最新評論的例子嗎?例如,收到新消息時?謝謝! – philfeyn 2010-10-19 01:48:59

+0

上面的代碼只是設置線程等待消息到達隊列的基本代碼。它不會影響服務或MSMQ以外的任何其他問題。我會在答案中添加一些代碼以改進它,但對於您使用MessageQueue類\ object – Neowizard 2010-10-19 07:13:36