I have make a filewatcher service that reads every XML files put in a directory and print the content on labels (Visual Studio 2012,Report viewer 2010). Service works fine on Windows 8, but on server 2008 R2 I get a crash every time I copy a file in the directory.
public partial class MyService : ServiceBase
{
public MyService ()
{
InitializeComponent();
GetSourcePath();
}
private void GetSourcePath()
{
RegistryKey myKey = Registry.LocalMachine.OpenSubKey("SOFTWARE\\Company\\MyService", false);
if (myKey == null)
{
fsw.Path = @"C:\Source\";
}
else
{
fsw.Path = (string)myKey.GetValue("SourcePath");
}
}
protected override void OnStart(string[] args)
{
base.OnStart(args);
fsw.EnableRaisingEvents = true;
}
protected override void OnPause()
{
base.OnPause();
fsw.EnableRaisingEvents = false;
}
protected override void OnContinue()
{
base.OnContinue();
GetSourcePath();
fsw.EnableRaisingEvents = true;
}
private void fsw_Created(object sender, FileSystemEventArgs e)
{
System.Threading.Thread.Sleep(2000);
ReportViewer reportViewer = new ReportViewer();
reportViewer.ProcessingMode = ProcessingMode.Local;
reportViewer.LocalReport.ReportPath = @"rptLabel.rdlc";
reportViewer.LocalReport.DataSources.Add(new ReportDataSource("DataSet", PrintLabel.GetPrintLabels(e.FullPath)));
reportViewer.RefreshReport();
AutoPrint.Export(reportViewer.LocalReport);
AutoPrint.Print();
}
protected override void OnStop()
{
fsw.EnableRaisingEvents = false;
}
}
And here the code for the other class
public class AutoPrint
{
private static int m_currentPageIndex;
private static IList<Stream> m_streams;
public static Stream CreateStream(string name, string fileNameExtension, Encoding encoding, string mimeType, bool willSeek)
{
Stream stream = new MemoryStream();
m_streams.Add(stream);
return stream;
}
public static void Export(LocalReport report)
{
string deviceInfo =
@"<DeviceInfo>
<OutputFormat>EMF</OutputFormat>
<PageWidth>10cm</PageWidth>
<PageHeight>4cm</PageHeight>
<MarginTop>0</MarginTop>
<MarginLeft>0</MarginLeft>
<MarginRight>0</MarginRight>
<MarginBottom>0</MarginBottom>
</DeviceInfo>";
Warning[] warnings;
m_streams = new List<Stream>();
try
{
report.Render("Image", deviceInfo, CreateStream, out warnings);
}
catch (Exception exc)
{
System.Diagnostics.EventLog.WriteEntry("My Service", DateTime.Now.ToLongTimeString() + " Error rendering print : " + exc.Message);
foreach (Stream stream in m_streams)
{
stream.Position = 0;
}
}
}
public static void Print()
{
PrintDocument printDoc = new PrintDocument();
if(printDoc.PrinterSettings.IsDefaultPrinter) printDoc.PrinterSettings.PrinterName = "Printer Name";
if (m_streams == null || m_streams.Count == 0) System.Diagnostics.EventLog.WriteEntry("MyService", DateTime.Now.ToLongTimeString() + " Error: no stream to print.");
if (!printDoc.PrinterSettings.IsValid)
{
System.Diagnostics.EventLog.WriteEntry("MyService", DateTime.Now.ToLongTimeString() + " Error: cannot find the default printer.");
}
else
{
printDoc.PrintPage += new PrintPageEventHandler(PrintPage);
m_currentPageIndex = 0;
printDoc.Print();
}
}
public static void PrintPage(object sender, PrintPageEventArgs ev)
{
try
{
Metafile pageImage = new Metafile(m_streams[m_currentPageIndex]);
// Adjust rectangular area with printer margins.
Rectangle adjustedRect = new Rectangle(
ev.PageBounds.Left - (int)ev.PageSettings.HardMarginX,
ev.PageBounds.Top - (int)ev.PageSettings.HardMarginY,
ev.PageBounds.Width,
ev.PageBounds.Height);
// Draw a white background for the report
ev.Graphics.FillRectangle(Brushes.White, adjustedRect);
// Draw the report content
ev.Graphics.DrawImage(pageImage, adjustedRect);
// Prepare for the next page. Make sure we haven't hit the end.
m_currentPageIndex++;
ev.HasMorePages = (m_currentPageIndex < m_streams.Count);
}
catch (Exception exc)
{
System.Diagnostics.EventLog.WriteEntry("MyService", DateTime.Now.ToLongTimeString() + " Error rendering print page: " + exc.Message + "Inner exception :" + exc.InnerException );
}
}
}
There is also a static class printLabel for the datas, but nothing interesting for this case. It only loads datas. Here is the first error message from the log Event
Application: MyService.exe Framework Version: v4.0.30319 Description: The process was terminated due to an unhandled exception. Exception Info: System.IO.FileNotFoundException Stack: at MyService.MyService.fsw_Created(System.Object, System.IO.FileSystemEventArgs) at System.IO.FileSystemWatcher.OnCreated(System.IO.FileSystemEventArgs) at System.IO.FileSystemWatcher.NotifyFileSystemEventArgs(Int32, System.String) at System.IO.FileSystemWatcher.CompletionStatusChanged(UInt32, UInt32, System.Threading.NativeOverlapped*) at System.Threading._IOCompletionCallback.PerformIOCompletionCallback(UInt32, UInt32, System.Threading.NativeOverlapped*)
Here the second message from the event log
Faulting application name: MyService.exe, version: 1.0.0.0, time stamp: 0x51349c1b Faulting module name: KERNELBASE.dll, version: 6.1.7601.17932, time stamp: 0x50327672 Exception code: 0xe0434352 Fault offset: 0x0000c41f Faulting process id: 0x2dc4 Faulting application start time: 0x01ce18d947393653 Faulting application path: C:\Program Files (x86)\Company\MyService\MyService.exe Faulting module path: C:\Windows\syswow64\KERNELBASE.dll Report Id: a27c24e2-84cc-11e2-bb34-0019992623e2
I made the same application as a console, it works perfectly.Maybe the service don't have the rights to read the files ? I someone has an idea ...