2014-08-28 168 views
0

這是一個簡單的問題,運行時不處理排隊的消息。現在,當我將其作爲Windows服務運行時,它不會處理私有隊列中的消息(使用MSMQ)。MSMQ應用程序作爲Windows服務

我試着以我的用戶帳戶和本地服務運行服務。在這兩種情況下,隊列中都充滿了消息,其中沒有一個正在處理。

請注意,Windows服務似乎運行正常:它是關聯Wcf服務打開並收聽。

只是爲了確保它不是權限問題,我授予我可以想到的每個組/用戶的完全訪問權限。這是處理隊列創建和主機初始化的代碼。請注意,在這次嘗試中,我將用戶的本地化命名更改爲他們的英文版本。另外請注意,我嘗試在所有可能的帳戶下安裝該服務:我自己以管理員身份運行,LocalSystem,LocalService和NetworkService。

namespace MachineCommunication.ZeissCMMAdapter 
{ 
    partial class ZeissService : ServiceBase 
    { 
     public ZeissService() 
     { 
      InitializeComponent(); 
     } 
     ServiceHost _host = null; 

     protected override void OnStart(string[] args) 
     { 
      Trace.WriteLine("Starting ZeissAdapter Service..."); 
      string adapterQueueName = ConfigurationManager.AppSettings["adapterQueueName"]; 

      // Create the transacted MSMQ queue if necessary. 

      MessageQueue adapterQueue; 
      if (!MessageQueue.Exists(adapterQueueName)) 
      { 
       Trace.WriteLine("Creating Queue: " + adapterQueueName); 
       adapterQueue = MessageQueue.Create(adapterQueueName, true); 
       adapterQueue.SetPermissions(@"NT AUTHORITY\System", MessageQueueAccessRights.FullControl); 
       adapterQueue.SetPermissions(@"ANONYMOUS LOGON", MessageQueueAccessRights.FullControl); 
       adapterQueue.SetPermissions(@"Everyone", MessageQueueAccessRights.FullControl); 
       adapterQueue.SetPermissions(@"my_user", MessageQueueAccessRights.FullControl); 
      } 
      else 
      { 
       Trace.WriteLine("Queue already exists: " + adapterQueueName); 
      } 


      string machineQueueName = ConfigurationManager.AppSettings["machineQueueName"]; 
      MessageQueue machineQueue; 
      // Create the transacted MSMQ queue if necessary. 
      if (!MessageQueue.Exists(machineQueueName)) 
      { 
       Trace.WriteLine("Creating Queue: " + machineQueueName); 
       machineQueue = MessageQueue.Create(machineQueueName, true); 
       machineQueue.SetPermissions(@"NT AUTHORITY\System", MessageQueueAccessRights.FullControl); 
       machineQueue.SetPermissions(@"ANONYMOUS LOGON", MessageQueueAccessRights.FullControl); 
       machineQueue.SetPermissions(@"Everyone", MessageQueueAccessRights.FullControl); 
       machineQueue.SetPermissions(@"my_user", MessageQueueAccessRights.FullControl); 
      } 
      using (_host = new ServiceHost(typeof(ZeissAdapterService))) 
      { 
       _host.Open(); 
       Console.WriteLine("The service is ready"); 
       Console.WriteLine("Press <Enter> to stop the service."); 
       Console.ReadLine(); 
      } 
     } 

     protected override void OnStop() 
     { 
      try 
      { 
       Trace.WriteLine("Shutting down Class-A E-mail Service..."); 
       if (_host != null && _host.State == CommunicationState.Opened) 
       { 
        _host.Close(); 
        _host = null; 
       } 
      } 
      catch (Exception ex) 
      { 
       Trace.WriteLine("Something went wrong closing the ServiceHost : " + ex.Message); 
       throw; 
      } 
     } 
    } 
} 

這裏是我的服務全面的app.config:

<?xml version="1.0" encoding="utf-8" ?> 
<configuration> 
    <startup> 
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" /> 
    </startup> 
    <appSettings> 
    <!-- use appSetting to configure MSMQ queue name --> 
    <add key="adapterQueueName" value=".\private$\Zeiss/ZeissAdapterService"/> 
    <add key="machineQueueName" value=".\private$\Zeiss/ZeissMachineService"/> 
    </appSettings> 
    <system.serviceModel> 
    <services> 
     <service name="MachineCommunication.ZeissCMMAdapter.ZeissAdapterService" behaviorConfiguration="DefaultBehavior"> 
     <!-- Define NetMsmqEndpoint --> 
     <host> 
      <baseAddresses> 
      <add baseAddress="http://localhost:12000/" /> 
      </baseAddresses> 
     </host> 
     <endpoint address="net.msmq://localhost/private/Zeiss/ZeissAdapterService" binding="netMsmqBinding" bindingConfiguration="TransactedBinding" contract="MachineCommunication.Contracts.AdapterContracts.IAdapterService"/> 
     <endpoint address="net.msmq://localhost/private/Zeiss/ZeissMachineService" binding="netMsmqBinding" bindingConfiguration="TransactedBinding" contract="MachineCommunication.MachineTypeSpecificInfrastructure.ZeissInfrastructure.IZeissListener"/> 
     <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" /> 
     </service> 
    </services> 
    <behaviors> 
     <serviceBehaviors> 
     <behavior name="DefaultBehavior"> 
      <serviceDebug includeExceptionDetailInFaults="true"/> 
      <serviceMetadata httpGetEnabled="true"/> 
     </behavior> 
     </serviceBehaviors> 
    </behaviors> 
    <bindings> 
     <netMsmqBinding> 
     <binding name="TransactedBinding" deadLetterQueue="System" useActiveDirectory ="False" useMsmqTracing="True"> 
      <security mode="None"> 
      <message clientCredentialType="None"/> 
      <transport msmqAuthenticationMode="None" msmqProtectionLevel="None" /> 
      </security> 
     </binding> 
     </netMsmqBinding> 
    </bindings> 
    </system.serviceModel> 
    <system.diagnostics> 
    <trace autoflush="true" /> 
    <sources> 
     <source name="System.ServiceModel" 
       switchValue="Information, ActivityTracing" 
       propagateActivity="true"> 
     <listeners> 
      <add name="sdt" 
       type="System.Diagnostics.XmlWriterTraceListener" 
       initializeData= "SdrConfigExample.e2e" /> 
     </listeners> 
     </source> 
    </sources> 
    </system.diagnostics> 
</configuration> 

下面是重現該問題有點快捷方式:在分佈式MSDN上的WCF代碼樣本,有兩涉及客戶端/服務器設置的MSMQ樣例;我修改了這個示例,將服務器安裝爲Windows服務。如果運行服務器並啓動客戶端,則所有消息都應該停留在服務器的隊列中,而不會進一步處理。這裏是一個鏈接到該樣本:

https://drive.google.com/file/d/0B5-APK5bfBpMUGU2cW5iaV9ybnM/edit?usp=sharing

回答

0

真正的問題只是,我試圖從一個到Console.ReadLine退出停止服務線程 - 運行的應用程序作爲服務時(顯然也許)不適用。我的不好,首先提出這個問題,我真的很抱歉。無論如何,所有的答案嘗試。

0

夫婦的想法。

  1. 試着讓服務像你一樣運行,但是作爲一個交互式用戶。

  2. 配置文件是否在正確的文件夾中?當你運行一個Windows服務,它默認的應用程序域到%SYSDIR%(你可以在OnStart中覆蓋)的基本目錄

除此之外,我建議你在示蹤劑添加和記錄什麼活動實際上正在發生或附加到調試器處理。

如果您需要重寫BaseDir。

System.IO.Directory.SetCurrentDirectory(AppDomain.CurrentDomain.BaseDirectory) 
0

很可能是由於權限。在網絡服務下運行的Windows服務或者不具有訪問MSMQ隊列的權限。你必須提供訪問權限。

在開發計算機或測試服務器上嘗試此操作,而不是生產。嘗試將「所有人」權限授予您正在與之通話的隊列,並在具有管理權限的用戶下運行該服務。如果它開始處理消息,那麼您會知道這是一個供應問題。

然後縮小範圍。刪除越來越多的權利,看看它是否仍然有效。

還可以做一些記錄,看看該服務已正確啓動。嘗試加載配置設置並記錄它們。嘗試使用Sysinternals DebugView查看它們或將它們記錄到文件中。如果服務正在記錄到文件中,並且您看到正確的配置項值被記錄,那麼您就會知道這裏沒有問題。

什麼我也看到的是,人們認爲他們應該訪問QUEUENAME/service.svc隊列。但這僅適用於IIS託管的WCF服務。

如果我是你,張貼整個配置。你沒有提供很多信息,我也看不出配置是否有問題。

+0

對不起在上面的代碼本地化用戶/組。實際上,我確實給了「每個人」(Tout le monde),網絡服務(SERVICERÉSEAU),本地服務等的完全訪問權限。我還嘗試以我自己的用戶身份(以管理員權限)運行服務,作爲本地服務,作爲本地系統作爲網絡服務。隊列總是保持不變(我刪除了它,並且在每次嘗試之前都爲我所能想到的每個帳戶分配了完整權限)。我將編輯我的文章,以包含更多可能對此問題負責的代碼。感謝您的答覆! – Strav 2014-08-30 02:13:39

+0

如果以編程方式將綁定設置爲MSMQ,該怎麼辦?我覺得它不是使用App.config通過MSMQ來收聽,而是使用默認值來收聽HTTP 我忘了確切的語法是什麼,但它是這樣的: _host.AddServiceEndpoint(typeof(MachineCommunication .MachineTypeSpecificInfrastructure.ZeissInfrastructure.IZeissListener) 新NetTcpBinding的(), 「SomeName」); 而且在同一個MSMQ隊列上也不可能有兩個監聽器。你們都應該爲他們提供自己的隊列。從配置中刪除一個以進行測試。 – 2014-09-02 13:26:17

相關問題