C# 将控制台应用程序转换为Windows服务
我正在尝试将生成pdf报告的控制台应用程序转换为windows服务。我的代码如下。我的方向对吗?我安装了此服务,启动/停止工作正常,但未生成报告!仅控制台应用程序就可以生成Output.pdf。我的目标是在服务启动时生成输出C# 将控制台应用程序转换为Windows服务,c#,.net,windows-services,report,console-application,C#,.net,Windows Services,Report,Console Application,我正在尝试将生成pdf报告的控制台应用程序转换为windows服务。我的代码如下。我的方向对吗?我安装了此服务,启动/停止工作正常,但未生成报告!仅控制台应用程序就可以生成Output.pdf。我的目标是在服务启动时生成输出 class Program : ServiceBase { public Program() { this.ServiceName = "My PdfGeneration"; } static void Main(string
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();
}
}
类程序:ServiceBase
{
公共计划()
{
this.ServiceName=“我的PDF生成”;
}
静态void Main(字符串[]参数)
{
运行(新程序());
}
启动时受保护的覆盖无效(字符串[]args)
{
WriteEntry(“我的PDF生成已开始”);
//base.OnStart(args);
//自定义渲染方法的参数
警告[]警告;
字符串[]流线;
string mimeType=string.Empty;//“application/pdf”;
字符串编码=string.Empty;
string filenameExtension=string.Empty;
字符串deviceInfo=“”+“PDF”+“15in”+“11in”+“0.5in”+“0.5in”+“0.5in”+“0.5in”+“0.5in”+”;
//创建到AdventureWorks2008R2数据库的SqlConnection。
SqlConnection=newsqlconnection(“数据源=localhost;初始目录=pod;集成安全=True”);
//为Sales.Customer表创建SqlDataAdapter。
SqlDataAdapter=新的SqlDataAdapter();
//一个表映射命名DataTable。
TableMappings.Add(“视图”、“路由清单”);
//打开连接。
connection.Open();
Console.WriteLine(“\nSQLConnection已打开”);
//创建SqlCommand以检索供应商数据。
SqlCommand=newsqlcommand(“从[pod].[dbo].[Route\u Manifest].[DriverName],[StopID],[CustomerID],[CustomerName],[InvoiceID],[last\u modified],[Amount],FROM[pod].[dbo].[Route\u Manifest]”,连接中选择前10位的[RouteID];
command.CommandType=CommandType.Text;
//设置SqlDataAdapter的SelectCommand。
adapter.SelectCommand=command;
command.ExecuteNonQuery();
//填充数据集。
数据集数据集=新数据集(“路由清单”);
adapter.Fill(数据集);
//设置reportviewver并指定路径
ReportViewer=新的ReportViewer();
viewer.ProcessingMode=ProcessingMode.Local;
viewer.LocalReport.ReportPath=@“C:\Documents and Settings\xxxxx\My Documents\Visual Studio 2008\Projects\PdfReportGeneration\PdfReportGeneration\Report.rdlc”;
//指定数据集语法=(datasetofreport.rdlc,querydataset);
viewer.LocalReport.DataSources.Add(新的ReportDataSource(“podDataSet\u Route\u Manifest”,dataset.Tables[0]);
//现在将其渲染为pdf
尝试
{
byte[]bytes=viewer.LocalReport.Render(“PDF”、deviceInfo、out-mimeType、out-encoding、out-filenameExtension、out-streamid、out-warnings);
//输出到bin目录
使用(System.IO.FileStream fs=new System.IO.FileStream(“output.pdf”,System.IO.FileMode.Create))
{
//文件保存到bin目录
fs.Write(字节,0,字节.长度);
}
Console.WriteLine(“\n YEP!!已生成报告:-”);
/*//将报告保存到D:\--以后
FileStream fsi=newfilestream(@“D:\output.pdf”,System.IO.FileMode.Create);
*/
}
捕获(例外e)
{
Console.WriteLine(“\n CHEY!!!遇到此异常:”,e);
}
//关闭连接。
connection.Close();
Console.WriteLine(“\nSQLConnection已关闭”);
Console.ReadLine();
}
受保护的覆盖void OnStop()
{
WriteEntry(“我的PDF生成已停止”);
base.OnStop();
}
}
我建议您将OnStart事件中的代码移动到单独的线程,因为
您的服务需要及时启动,否则可能会超时
启动时
例如
您可能还需要检查正在执行的用户(服务运行的用户上下文)
对您要写入的文件夹具有权限等
您还需要将错误写入事件日志,而不是写入
控制台窗口,如代码片段中所示(您的代码目前正在吞噬异常)
这就是为什么你不能指出哪里出了问题)
请在此阅读更多信息:
是和否,您应该做的是通过定义接口来定义您正在公开的操作契约 例如,请参见第9频道:
您应该将此服务定义为一个单独的库程序集(因为明天您将希望在其他地方托管此服务,并且很可能在开发时在控制台应用程序中托管此服务)
消费服务,您需要考虑是否应该从ASP.NET网页、Windows窗体程序或控制台实用程序中,真正取决于您的消费者场景,您希望在单独的类(在同一库组件中)将实际PDF功能进行外部化。因此,当你想在你的其他程序中做到这一点时,它不必与网络上的某个wcf服务进行通信,尽管这样的事情本身很好,但它在一定程度上影响了跨进程集成的性能。
关于正确写入日志的Onstart和Onstop的上述代码的日志写入问题。另外,渲染方法日志“YEP!!已生成报告:“Alway logged!!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
}
}
}