Click here to Skip to main content
Click here to Skip to main content
Articles » Languages » C# » Applications » Downloads
 
Add your own
alternative version

Storing ECG to a PACS

, 16 Oct 2008 Apache
An article on a service that will store an ECG copied to a directory at a PACS. (supported formats SCP-ECG, DICOM-ECG and a recent version of HL7 aECG)
ECGtoPACS_demo.zip
ECGtoPACS_demo
dicomcs.dll
ECGConversion.dll
ECGCpluginaECG.dll
ECGCpluginDICOM.dll
ECGtoPACS.exe
log4net.dll
ECGtoPACS_src.zip
ECGtoPACS_src
ECGtoPACS.csproj.user
ECGtoPACS.ico
ECGtoPACS.suo
libs
dicomcs.dll
ECGConversion.dll
ECGCpluginaECG.dll
ECGCpluginDICOM.dll
log4net.dll
/***************************************************************************
Copyright 2008, Thoraxcentrum, Erasmus MC, Rotterdam, The Netherlands

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

	http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

Written by Maarten JB van Ettinger.

****************************************************************************/
using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.IO;
using System.ServiceProcess;
using System.Threading;

using ECGConversion;
using ECGConversion.ECGManagementSystem;

namespace ECGtoPACS
{
	public class ECGtoPACS : System.ServiceProcess.ServiceBase
	{
		/// <summary> 
		/// Required designer variable.
		/// </summary>
		private System.ComponentModel.Container components = null;
		private System.IO.FileSystemWatcher _ECGWatcher;
		private String _FailDir;
		private String _SuccessDir;
		private Boolean _EraseOnSuccess;
		private ECGConfig _FormatConfig;
		private ECGConfig _SystemConfig;

		public ECGtoPACS()
		{
			// This call is required by the Windows.Forms Component Designer.
			InitializeComponent();

			_ECGWatcher.Created += new System.IO.FileSystemEventHandler(_ECGWatcher_Created);
		}

		// The main entry point for the process
		public static void Main(String[] args)
		{
			try
			{
				if ((args.Length == 1)
				&&	(String.Compare(args[0], "runcmd") == 0))
				{
					ECGtoPACS temp = new ECGtoPACS();

					temp.OnStart(null);
				
					while (true)
						Thread.Sleep(1000);
				}
				else
				{
					System.ServiceProcess.ServiceBase[] ServicesToRun;
	
					// More than one user Service may run within the same process. To add
					// another service to this process, change the following line to
					// create a second service object. For example,
					//
					//   ServicesToRun = new System.ServiceProcess.ServiceBase[] {new Service1(), new MySecondUserService()};
					//
					ServicesToRun = new System.ServiceProcess.ServiceBase[] { new ECGtoPACS() };

					System.ServiceProcess.ServiceBase.Run(ServicesToRun);
				}
			}
			catch (Exception ex)
			{
				ServiceLogger.Instance.Log(ex, EventLogEntryType.Error);
			}
		}

		/// <summary> 
		/// Required method for Designer support - do not modify 
		/// the contents of this method with the code editor.
		/// </summary>
		private void InitializeComponent()
		{
			_ECGWatcher = new System.IO.FileSystemWatcher();
			((System.ComponentModel.ISupportInitialize)(_ECGWatcher)).BeginInit();
			// 
			// newECGWatcher
			// 
			_ECGWatcher.EnableRaisingEvents = true;
			// 
			// ECGtoPACS
			// 
			this.ServiceName = "ECG to PACS";
			((System.ComponentModel.ISupportInitialize)(_ECGWatcher)).EndInit();
		}

		/// <summary>
		/// Clean up any resources being used.
		/// </summary>
		protected override void Dispose( bool disposing )
		{
			if( disposing )
			{
				if (components != null) 
				{
					components.Dispose();
				}
			}
			base.Dispose( disposing );
		}

		/// <summary>
		/// Set things in motion so your service can do its work.
		/// </summary>
		protected override void OnStart(String[] args)
		{
			if (args != null)
				ServiceLogger.Instance.EventLogger = this.EventLog;

			LoadConfig();

			if (Directory.Exists(_ECGWatcher.Path))
			{
				String[] files = Directory.GetFiles(_ECGWatcher.Path);

				if (files == null)
					return;

				foreach (String file in files)
					StoreECG(file);
			}
		}
 
		/// <summary>
		/// Stop this service.
		/// </summary>
		protected override void OnStop()
		{
			if (_ECGWatcher != null)
			{
				_ECGWatcher.Dispose();
				_ECGWatcher = null;
			}
		}

		/// <summary>
		/// Loading configuration
		/// </summary>
		private void LoadConfig()
		{
			_ECGWatcher.Path = System.Configuration.ConfigurationSettings.AppSettings["ImportDir"];
			_FailDir = Path.Combine(_ECGWatcher.Path, "failed");
			_SuccessDir = Path.Combine(_ECGWatcher.Path, "success");
			_EraseOnSuccess = String.Compare(System.Configuration.ConfigurationSettings.AppSettings["EraseOnSuccess"], "true", true) == 0;

			_FormatConfig = ECGConverter.Instance.getConfig("DICOM-ECG");

			IECGManagementSystem manSys = ECGConverter.Instance.getECGManagementSystem("PACS");
			_SystemConfig = manSys == null ? null : manSys.Config;

			LoadConfig(_FormatConfig);
			LoadConfig(_SystemConfig);
		}

		/// <summary>
		/// Loading config elements for an ECGConfig object.
		/// </summary>
		/// <param name="cfg">the ECGConfig object</param>
		private void LoadConfig(ECGConfig cfg)
		{
			if (cfg != null)
			{
				String name, val;
				bool must;

				for (int i=0,end = cfg.NrConfigItems;i < end;i++)
				{
					cfg.getConfigItem(i, out name, out must);

					val = System.Configuration.ConfigurationSettings.AppSettings[name];

					if (val != null)
						cfg[name] = val;
				}
			}
		}

		/// <summary>
		/// New file has been added to the 
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		private void _ECGWatcher_Created(object sender, System.IO.FileSystemEventArgs e)
		{
			StoreECG(e.FullPath);
		}

		private void StoreECG(String filePath)
		{
			if (System.IO.File.Exists(filePath))
			{
				bool bFail = false;

				try
				{
					UnknownECGReader reader = new UnknownECGReader();

					IECGFormat src = reader.Read(filePath);

					if ((reader.getError() == 0)
					&&	(src != null)
					&&	src.Works())
					{
						IECGManagementSystem pacs = ECGConverter.Instance.getECGManagementSystem("PACS");
						
						pacs.Config.Set(_SystemConfig);

						if (pacs.SaveECG(src, null, _FormatConfig) != 0)
						{
							ServiceLogger.Instance.Log("Storing ECG to PACS failed!", EventLogEntryType.FailureAudit);

							bFail = true;
						}
					}
					else
					{
						ServiceLogger.Instance.Log("Unknown ECG file type!", EventLogEntryType.FailureAudit);

						bFail = true;
					}
				}
				catch (Exception ex)
				{
					ServiceLogger.Instance.Log(ex, EventLogEntryType.Error);
					bFail = true;
				}

				if (bFail)
				{
					try
					{
						if (!Directory.Exists(_FailDir))
							Directory.CreateDirectory(_FailDir);

						String
							tempPath = Path.Combine(
							_FailDir,
							Path.GetFileName(filePath)),
							toPath = tempPath + ".0";

						for (int i=1;File.Exists(toPath);i++)
						{
							toPath = tempPath + "." + i.ToString();
						}

						File.Move(filePath, toPath);
					}
					catch (Exception ex)
					{
						ServiceLogger.Instance.Log(ex, EventLogEntryType.Error);
					}
				}
				else if (_EraseOnSuccess)
				{
					File.Delete(filePath);
				}
				else
				{
					if (!Directory.Exists(_SuccessDir))
						Directory.CreateDirectory(_SuccessDir);

					String
						tempPath = Path.Combine(
						_SuccessDir,
						Path.GetFileName(filePath)),
						toPath = tempPath + ".0";

					for (int i=1;File.Exists(toPath);i++)
					{
						toPath = tempPath + "." + i.ToString();
					}

					File.Move(filePath, toPath);
				}
			}
		}
	}
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Apache License, Version 2.0

Share

About the Author

MJB van Ettinger
Software Developer Erasmus MC
Netherlands Netherlands
No Biography provided

| Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.141223.1 | Last Updated 16 Oct 2008
Article Copyright 2008 by MJB van Ettinger
Everything else Copyright © CodeProject, 1999-2014
Layout: fixed | fluid