2016-11-01 47 views
1

Windows服務我的編碼是不工作:我的自定義Windows服務無法使用Windows消息隊列工作

  • 預期的funcionality:服務應該從Windows消息隊列(MSMQ)接收郵件,寫郵件在.txt文件上。

  • 它的工作原理,當我運行它不是作爲一種服務(直接從Visual Studio)

  • 當我安裝它作爲一個服務,我可以啓動它,但它不會做任何事情,不創建/寫入.txt文件的任何地方

(我知道這不是寫文件,在其他地方,因爲當我從運行VS程序的消息仍然在排隊,所以他們並沒有被取出服務)

運行它作爲一個服務,從Visual Studio中運行它是下一個:

namespace ComponentAtrapador 
{ 
    static class Program 
    { 
     /// <summary> 
     /// The main entry point for the application. 
     /// </summary> 
     static void Main() 
     { 
#if DEBUG 
      Service1 myService = new Service1(); 
      myService.startMethod(); 
      System.Threading.Thread.Sleep(System.Threading.Timeout.Infinite); 


#else 
      ServiceBase[] ServicesToRun; 
      ServicesToRun = new ServiceBase[] 
      { 
       new Service1() 
      }; 
      ServiceBase.Run(ServicesToRun); 
#endif 
     } 
    } 
} 

這裏的服務代碼(如果我運行它DEBUG將沒有我不必把它安裝作爲服務運行):

namespace ComponentAtrapador 
{ 
     public partial class Service1 : ServiceBase 
     { 
     private System.Timers.Timer _timer; 
     private System.ComponentModel.IContainer components1; 
     private System.Diagnostics.EventLog eventLog1; 

     public void startMethod() 
     { 
      OnStart(null); 
     } 
     public Service1() 
     { 
      InitializeComponent(); 
      eventLog1 = new System.Diagnostics.EventLog(); 
      if (!System.Diagnostics.EventLog.SourceExists("MySource")) 
      { 
       System.Diagnostics.EventLog.CreateEventSource(
        "MySource", "MyNewLog"); 
      } 
      eventLog1.Source = "MySource"; 
      eventLog1.Log = "MyNewLog"; 
     } 

     protected override void OnStart(string[] args) 
     { 
      eventLog1.WriteEntry("In OnStart"); 
       _timer = new System.Timers.Timer(); 
       _timer.Interval = 5000; // 5 seconds 
       _timer.Elapsed += new System.Timers.ElapsedEventHandler(this.OnTimer); 
       _timer.Start(); 
     } 

     protected override void OnStop() 
     { 
      _timer.Stop(); 
     } 

     public void OnTimer(object sender, System.Timers.ElapsedEventArgs args) 
     { 
      string nombreArchivo = "archivoMensaje"; 
        MessageQueue messageQueue = new MessageQueue(@".\Private$\SomeTestName"); 
        System.Messaging.Message[] messages = messageQueue.GetAllMessages(); 

        System.Messaging.Message m = new System.Messaging.Message(); 
        foreach (System.Messaging.Message message in messages) 
        { 
         message.Formatter = new XmlMessageFormatter(new String[] { "System.String,mscorlib" }); 
         string text = message.Body.ToString(); 
         System.IO.File.WriteAllText(AppDomain.CurrentDomain.BaseDirectory + nombreArchivo + Properties.Settings.Default.SettingNumero + ".txt", text); 
         Properties.Settings.Default.SettingNumero++; 
         Properties.Settings.Default.Save(); 
         //Do something with the message. 
        } 
        // after all processing, delete all the messages 
        messageQueue.Purge(); 

      //} 

     } 
    } 
} 
+0

精心打造的問題。謝謝。 – itsme86

+0

當您作爲窗口服務運行vs從Visual Studio運行時,這裏有兩個相關的區別。 1)程序默認運行爲本地系統帳戶,而不是登錄用戶帳戶。 2)工作目錄是system32文件夾,而不是exe的位置。 – Vince

+0

檢查您的Windows服務是否配置了可訪問私有隊列的帳戶@「。\ Private $ \ SomeTestName – Vince

回答

0

原來的服務沒有足夠的權限,通過設置的serviceProcessInstaller固定它在Visual Studio的服務對用戶,所以當我安裝它會要求憑據。只需輸入「./ [用戶名]」,當它要求我的用戶名爲它的工作。

修復它的另一種方法是進入任務管理器>服務>右鍵單擊服務>屬性>安全性。並更改那裏的權限。

0

這就是日誌非常有用的地方,在你的OnTimer方法中放置了兩個eventLog1.WriteEntry(),你會看到它失敗的地方。 我會檢查

  1. 我收到了多少條消息。
  2. 我會放一個eventLog1.WriteEntry()內循環,看看有什麼是與每個消息等發生...
相關問題