2013-10-24 174 views
4

我正嘗試將生成pdf報告的控制檯應用程序轉換爲Windows服務。我的代碼如下。我在正確的方向嗎?我安裝了這項服務並開始/停止工作正常,但沒有生成報告!單獨的控制檯應用程序可以很好地生成Output.pdf。我的目標是在服務啓動時生成輸出。將控制檯應用程序轉換爲Windows服務

class Program : ServiceBase 
{ 
    public Program() 
    { 
     this.ServiceName = "My PdfGeneration"; 
    } 
    static void Main(string[] args) 
    { 

     ServiceBase.Run(new Program()); 
    } 
    protected override void OnStart(string[] args) 
    { 
     EventLog.WriteEntry("My PdfGeneration Started"); 
     //base.OnStart(args); 
     //Customise parameters for render method 
     Warning[] warnings; 
     string[] streamIds; 
     string mimeType = string.Empty; //"application/pdf"; 
     string encoding = string.Empty; 
     string filenameExtension = string.Empty; 
     string deviceInfo = "<DeviceInfo>" + "<OutputFormat>PDF</OutputFormat>" + "<PageWidth>15in</PageWidth>" + "<PageHeight>11in</PageHeight>" + "<MarginTop>0.5in</MarginTop>" + "<MarginLeft>0.5in</MarginLeft>" + "<MarginRight>0.5in</MarginRight>" + "<MarginBottom>0.5in</MarginBottom>" + "</DeviceInfo>"; 

     //Create a SqlConnection to the AdventureWorks2008R2 database. 
     SqlConnection connection = new SqlConnection("data source=localhost;initial catalog=pod;integrated security=True"); 

     //Create a SqlDataAdapter for the Sales.Customer table. 
     SqlDataAdapter adapter = new SqlDataAdapter(); 

     // A table mapping names the DataTable. 
     adapter.TableMappings.Add("View", "Route_Manifest"); 

     // Open the connection. 
     connection.Open(); 
     Console.WriteLine("\nThe SqlConnection is open."); 

     // Create a SqlCommand to retrieve Suppliers data. 
     SqlCommand command = new SqlCommand("SELECT TOP 10 [RouteID],[FullTruckID],[DriverID],[DriverName],[StopID],[CustomerID],[CustomerName],[InvoiceID],[last_modified],[Amount] FROM [pod].[dbo].[Route_Manifest]", connection); 
     command.CommandType = CommandType.Text; 

     // Set the SqlDataAdapter's SelectCommand. 
     adapter.SelectCommand = command; 
     command.ExecuteNonQuery(); 

     // Fill the DataSet. 
     DataSet dataset = new DataSet("Route_Manifest"); 
     adapter.Fill(dataset); 

     //Set up reportviewver and specify path 
     ReportViewer viewer = new ReportViewer(); 
     viewer.ProcessingMode = ProcessingMode.Local; 
     viewer.LocalReport.ReportPath = @"C:\Documents and Settings\xxxxx\My Documents\Visual Studio 2008\Projects\PdfReportGeneration\PdfReportGeneration\Report.rdlc"; 

     //specify the dataset syntax = (datasetofreport.rdlc,querydataset); 
     viewer.LocalReport.DataSources.Add(new ReportDataSource("podDataSet_Route_Manifest", dataset.Tables[0])); 


     //Now render it to pdf 
     try 
     { 
      byte[] bytes = viewer.LocalReport.Render("PDF", deviceInfo, out mimeType, out encoding, out filenameExtension, out streamIds, out warnings); 
      //output to bin directory 
      using (System.IO.FileStream fs = new System.IO.FileStream("output.pdf", System.IO.FileMode.Create)) 
      { 
       //file saved to bin directory 
       fs.Write(bytes, 0, bytes.Length); 
      } 
      Console.WriteLine("\n YEP!! The report has been generated:-)"); 

      /*   //Save report to D:\ -- later 
         FileStream fsi = new FileStream(@"D:\output.pdf", System.IO.FileMode.Create); 
      */ 
     } 
     catch (Exception e) 
     { 
      Console.WriteLine("\n CHEY!!!this Exception encountered:", e); 
     } 


     // Close the connection. 
     connection.Close(); 
     Console.WriteLine("\nThe SqlConnection is closed."); 
     Console.ReadLine(); 

    } 
    protected override void OnStop() 
    { 
     EventLog.WriteEntry("My PdfGeneration Stopped"); 
      base.OnStop(); 
    } 

} 
+0

On Onstart和Onstop上面的代碼寫入日誌正確寫入日誌。同時渲染方法日誌「YEP !!報告已生成:」也記錄! – flute

回答

7

我會建議你在你的OnStart事件中的代碼移到一個單獨的線程,因爲 您的服務將需要及時事情開始,否則它可能超時 上啓動。

using System.ServiceProcess; 
using System.Threading; 

namespace myService 
{ 
    class Service : ServiceBase 
    { 
     static void Main() 
     { 
      ServiceBase.Run(new Service()); 
     } 

     public Service() 
     { 
      Thread thread = new Thread(Actions); 
      thread.Start(); 
     } 

     public void Actions() 
     { 
      // Do Work 
     } 
    } 
} 

您可能還需要檢查,如果(在其中運行服務用戶上下文)執行用戶 有權限的文件夾你寫等

你會還需要寫你的錯誤到事件日誌,而不是寫他們到 控制檯窗口就像你的代碼片段所示(你的代碼吞嚥異常在此刻爲 這就是爲什麼你不能指出什麼是錯誤的)

更多在這裏: C# Basics: Creating a Windows Service

0

是的,沒有,你應該做的是定義什麼OperationContract的你是通過定義一個接口暴露的過程。

例如看到這個信道9:
http://channel9.msdn.com/Shows/Endpoint/Endpoint-Screencasts-Creating-Your-First-WCF-Service

你應該定義該服務是獨立的庫組件(因爲明天你要到別的地方舉辦這項服務並且很可能在開發,在控制檯程序)。

如果應該從asp.net網頁,Windows窗體程序或控制檯實用程序中使用服務,您需要考慮這些服務,這些服務實際上取決於您的用戶場景,您希望將實際的PDF功能外部化單獨的類(在相同的庫程序集中),以便您希望在其中一個其他程序中能夠這樣做的那一天,它不必與網絡上的某個wcf服務進行通信,儘管這樣的事情是非常好的本身會影響整個流程在有限程度上的整合。

相關問題