2010-10-18 75 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