将控制台应用程序转换为Windows服务 [英] Converting Console app to Windows Service

查看:71
本文介绍了将控制台应用程序转换为Windows服务的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试将生成pdf报告的控制台应用程序转换为Windows服务。我的代码如下。我的方向正确吗?我安装了此服务,启动/停止工作正常,但未生成报告!单独使用控制台应用程序可以很好地生成Output.pdf。我的目标是在服务启动时生成输出。

Am trying to convert my console application, which generates pdf reports, into a windows service. My code is as follows. Am I on the right direction? I installed this service and start/stop works fine but no report is generated! The console app alone works fine to generate Output.pdf. My aim is to Generate ouput when the service starts.

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();
    }

}


推荐答案

我建议您将OnStart事件中的代码移动到单独的线程中,因为
您的服务将需要及时启动,否则启动时可能会超时

I would advise that you move the code in your OnStart event to a separate thread, since your service will need to start in a timely matter, else it can potentially time out on start up.

例如

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
        }
    }
}

您可能还想检查执行用户(运行服务的用户上下文)
是否具有权限

You might also want to check if the executing user (user context in which the service runs) has rights to the folder you're writing to etc.

您还需要将错误写入事件日志,而不是像将其写入
控制台窗口一样在您的代码段中看到(您的代码现在吞没
的异常,这就是为什么您无法指出发生了什么问题的原因)

You will also need to write your errors to the event log instead of writing them to the console window like seen in your snippet (your code is swallowing exceptions at the moment thats why you cant pin point whats going wrong)

在此处了解更多b C#基础知识:创建Windows服务

这篇关于将控制台应用程序转换为Windows服务的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆