Monthly Archives: August 2011

XmlElementEx – a few XmlElement extension methods

I thought I’d just share a few extension methods I created for myself to handle a hew things with the XmlElement, XmlNode and XmlDocument classes of System.Xml namespace.

These include:

  • ReadXmlElementAttr
  • CreateAttributeWithValue
  • SetAttributeValue
  • AppendElementWithText
  • AppendElementWithCDATA
using System.Xml;

    public static class XmlElementEx
    {
        public static string ReadXmlElementAttr(this XmlElement e, string attrName, string defaultValue = "")
        {
            try
            {
                if (e.HasAttribute(attrName))
                    return e.Attributes.GetNamedItem(attrName).Value;
            }
            catch { }
            return defaultValue;
        }
        public static string ReadXmlElementAttr(this XmlNode e, string attrName, string defaultValue = "")
        {
            return ReadXmlElementAttr((XmlElement)e, attrName, defaultValue);
        }
        public static XmlAttribute CreateAttributeWithValue(this XmlDocument xml, string attrName, bool value)
        {
            return xml.CreateAttributeWithValue(attrName, value.ToString());
        }
        public static XmlAttribute CreateAttributeWithValue(this XmlDocument xml, string attrName, int value)
        {
            return xml.CreateAttributeWithValue(attrName, value.ToString());
        }
        public static XmlAttribute CreateAttributeWithValue(this XmlDocument xml, string attrName, long value)
        {
            return xml.CreateAttributeWithValue(attrName, value.ToString());
        }

        public static XmlAttribute CreateAttributeWithValue(this XmlDocument xml, string attrName, string value)
        {
            XmlAttribute attr;
            attr = xml.CreateAttribute(attrName);
            attr.Value = value;
            return attr;
        }
        public static XmlAttribute SetAttributeValue(this XmlNode e, string attrName, string value)
        {
            return SetAttributeValue((XmlElement)e, attrName, value);
        }
        public static XmlAttribute SetAttributeValue(this XmlElement e, string attrName, string value)
        {
            if (e.HasAttribute(attrName))
                e.Attributes[attrName].Value = value;
            else
                e.Attributes.Append(CreateAttributeWithValue(e.OwnerDocument, attrName, value));
            return e.Attributes[attrName];
        }

        public static XmlElement AppendElementWithText(this XmlElement e, string elementName, string text)
        {
            XmlElement newElement = e.OwnerDocument.CreateElement(elementName);
            newElement.InnerText = text;
            e.AppendChild(newElement);
            return newElement;
        }
        public static XmlElement AppendElementWithCDATA(this XmlElement e, string elementName, string cdataText)
        {
            XmlElement newElement = e.OwnerDocument.CreateElement(elementName);
            XmlCDataSection commentNode = e.OwnerDocument.CreateCDataSection(cdataText);
            newElement.AppendChild(commentNode);
            e.AppendChild(newElement);
            return newElement;
        }
    }

 

Is it my time or not?

Sounds like another philosophical question but no, you can relax. This is another developmental (yes almost mental) posting.

Say you need to create a piece of functionality that must only operate within a predefined time period of a day – call it a ‘service window’. It could be that you may even need several of these ‘windows’ per day – i.e. if there is a pause period inside the day and work must be processed before (up until) and after the pause.

For this kind of functionality I created a ‘ServiceWindows’ class. It basically host a list of ‘from’ and ‘to’ times plus methods that makes it possible to find out if a specified time is somewhere ‘inside’ or ‘outside’ any ‘service window’. Additionally the class can be ‘populated’ from an xml config string so it can be used in applications that operates from xml config files.

So without much further chit-chatting here is the guts of the class (not for sensitive readers 😉

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;

    public class ServiceWindow
    {
        public ServiceWindow(DateTime from, DateTime to)
        {
            From = from;
            To = to;
        }
        public DateTime From { get; set; }
        public DateTime To { get; set; }
    }

    public class ServiceWindows
    {
        private List<ServiceWindow> times = new List<ServiceWindow>();
        public List<ServiceWindow> Times { get return times; } }

        public void AddTimeWindow(DateTime fromTime, DateTime toTime)
        {
            times.Add(new ServiceWindow(fromTime, toTime));
        }
        public bool IsInTimeWindow()
        {
            return IsInTimeWindow(DateTime.Now);
        }
        public bool IsInTimeWindow(DateTime nowTime)
        {
            if (times.Count == 0)
                return true;
            else
                return (from t in times
                        where t.From.TimeOfDay <= nowTime.TimeOfDay &&
                              t.To.TimeOfDay >= nowTime.TimeOfDay
                        select t).Count() > 0;
        }

        public void CreateFromConfig(string config)
        {
            if (config.Length > 0)
            {
                times.Clear();
                XmlDocument configXml = new XmlDocument();
                configXml.LoadXml(config);
                XmlElement root = configXml.DocumentElement;
                foreach (XmlNode windowItem in root.SelectNodes("window"))
                {
                    try
                    {
                        DateTime fromTime = DateTime.Parse(windowItem.ReadXmlElementAttr("from", "00:00:01"));
                        DateTime toTime = DateTime.Parse(windowItem.ReadXmlElementAttr("to", "23:59:59"));
                        times.Add(new ServiceWindow(fromTime, toTime));
                    }
                    catch { }
                }
            }
        }
        public string ToConfig()
        {
            StringBuilder sb = new StringBuilder();
            sb.AppendLine("<serviceWindows>");
            if (times.Count > 0)
                foreach (ServiceWindow timeWindow in times)
                    sb.AppendLine(string.Format("<window from=\"{0}\" to=\"{1}\" />",
                              timeWindow.From.ToString("HH:mm:ss"),
                              timeWindow.To.ToString("HH:mm:ss")));

            sb.AppendLine("</serviceWindows>");
            return sb.ToString();
        }

        public override string ToString()
        {
            StringBuilder sb = new StringBuilder();
            if (times.Count > 0)
                foreach (ServiceWindow timeWindow in times)
                    sb.Append(string.Format("{0} to {1} and ",
                           timeWindow.From.ToString("HH:mm:ss"),
                           timeWindow.To.ToString("HH:mm:ss")));
            else
                sb.Append("None");
            return sb.ToString().Trim(' ', 'a', 'n', 'd');
        }
    }

I noticed that I included an XmlNode extension method (ReadXmlElementAttr) that I defined elsewhere but all it does is to read an xml element attribute or provide a default value if not found. I’ll list that class here on my blog too soon.

It’s environmental

Just have to share this quickly. If you have a problem on a machine/computer/server and you cannot pin-point the exact problem you can always blame it on being ‘environmental’ with the emphasis on the ‘mental’ part…

Waiting for your exit

With a heading like this the post could be mistaken for something more philosophical but fortunately this is a plain developmental posting 🙂

Suppose you have some program that does some work and then have to ‘sleep’ for a while before doing some more work – like a service checking or polling stuff. You can simply use something like a Thread.Sleep() but that also means the thread cannot do or respond to anything else during that time – like the program or service stopping. That would mean the stopping process has to wait until the ‘sleeping’ thread becomes active again.

A solution to this is by having a variable or property that indicates if the program or service is still running and having the ‘waiting’ routine wait in little ‘jumps’ checking the ‘IsRunning’ variable each time and then waiting a little bit more until the full ‘sleeping’ period time is done.

private void BackgroundWaitIsPolling(int nextWaitInterval)
{
   int waitTimeRemaining;
   int decrementBy = 2000;
   if (IsRunning)
   {
       try
       {
           if ((nextWaitInterval <= decrementBy) && (nextWaitInterval > 0))
           {
               Thread.Sleep(nextWaitInterval);
           }
           else
           {
               waitTimeRemaining = nextWaitInterval;
               while (IsRunning && (waitTimeRemaining > 0))
               {
                  if (waitTimeRemaining <= decrementBy)
                  {
                      waitTimeRemaining = 0;
                  }
                  else
                  {
                      waitTimeRemaining -= decrementBy;
                  }
                  if (decrementBy > 0)
                  {
                      Thread.Sleep(decrementBy);
                  }
               }
           }
        }
        catch { }
   }
}

 

Extending the TreeView control

Here is a little Extension class to the TreeView control. I created it to add some new functionality that is not available in the base control. It is based on the System.Windows.Forms namespace TreeView but probably can be use relatively easy without too much modification on WPF as well (haven’t tried it yet)

public static class TreeViewEx
    {
        public static int CheckedCount(this TreeView tvw)
        {
            int count = 0;
            count = (from TreeNode n in tvw.Nodes
                     where n.Checked
                     select n).Count();
            foreach (TreeNode childNode in tvw.Nodes)
            {
                count += CheckedCount(childNode);
            }

            return count;
        }
        public static int CheckedCount(this TreeNode parentNode)
        {
            int count = 0;
            count = (from TreeNode in parentNode.Nodes
                     where n.Checked
                     select n).Count();
            foreach (TreeNode childNode in parentNode.Nodes)
            {
                count += CheckedCount(childNode);
            }
            return count;
        }
        public static List<TreeNode> CheckedNodes(this TreeView tvw)
        {
            List<TreeNode> checkedNodes = new List<TreeNode>();
            foreach(TreeNode node in (from TreeNode in tvw.Nodes
                         select n))
            {
                if (node.Checked)
                    checkedNodes.Add(node);
                checkedNodes.AddRange(node.CheckedNodes().ToArray());
            }
            return checkedNodes;
        }
        public static List<TreeNode> CheckedNodes(this TreeNode parentNode)
        {
            List<TreeNode> checkedNodes = new List<TreeNode>();
            foreach (TreeNode node in (from TreeNode in parentNode.Nodes
                                           select n))
            {
                if (node.Checked)
                    checkedNodes.Add(node);
                checkedNodes.AddRange(node.CheckedNodes().ToArray());
            }
            return checkedNodes;
        }
        public static void ExpandAllParents(this TreeNode node)
        {
            TreeNode parent = node.Parent;
            while (parent != null)
            {
                parent.Expand();
                parent = parent.Parent;
            }
        }
    }

Microsoft Access Database Engine for 64-bit

Wow I must have missed this one when it was released but it (has the potential to) solves some problems with accessing Access databases (*.mdb) from a 64-bit process. I haven’t tested it yet and the description mention that you can only use the 32-bit driver on Windows XP (sp3) but at least it should work for Windows 7 (and yes that other one…Vista as well).

Download link: Microsoft Access Database Engine 2010 Redistributable

http://www.microsoft.com/download/en/details.aspx?displaylang=en&id=13255

 

Medical stuff

Here is a ‘wild’ idea… just an idea. Use it, don’t use…

Almost every day we (mwoa included) hear how medial aids are screwing us left right and… you know where else. They might call it ‘service’ or whatever citing that they also must ‘cover’ their expenses. I’ll admit, this is not a ‘simple’ matter because if it was someone would have solved it long ago…

Now, what if (and it is a big ‘if’) the government declares some basic medical procedures ‘free’. The most common ones that are really necessary for the general public. I’m not talking about cosmetic things like making you look and feel better but rather the things that will benefit the public or is life threatening.

Now I know some people will go.. ‘but you can go to a state hospital and get some things ‘free’ anyway’… The idea I have here is that you don’t need to have a medical aid at all for basic stuff like colds, flues,  measles, fevers, toothaches, strokes, heart attacks and also all childhood illnesses. Lets be honest, even the medial aids hate those things as well – just more paperwork for what? The problem with the current set up for free ‘procedures’ are they are provided by people that are not terribly motivated to do so – and working in bad conditions in state hospitals. No doctor or nurse that has a (working) self esteem wants to be there – not to mention the bad pay. And that is perhaps (one of) the root of the problem.

The flip side is because the government would be paying for these things it would be in ‘their’ interest too to have ‘healthy’ people. Ban smoking, oily fast foods (hehe oops sorry McDonalds..), pollution (which also makes people sick), stressful activities like traffic jams (not sure how ya gona solve that one) etc. There, that should make everyone (except you know who…) happy…

 

The bad apple

There is an old saying that one bad apple can make the whole fruit basket go bad. Lately the big ‘apple’  has been getting bigger and ‘badder’. Now, I’m not a really a fan of them (Apple) – having a more MS background but I won’t bash them unless it is really necessary. Truth is, they have/had it coming.

In the latest news (just in case you haven’t been keeping up to date) Apple is suing competitors left right and center – this all because of ‘patent’ issues. Again, I’m not an Samsung/Android/Google specific fan but, suing someone because they have a product that looks like yours and you didn’t even invent the original concept (patents were bought from others) just means one thing – you suck at business. The fact that you had to buy a patent for something you want to sell means your only intent is to blackmail/screw others with it. Yes, many companies does it these days (even MS) and personally I think the idea stinks (sucks/blows or whatever way you want to refer to it). As far as I’m concern patents should not be purchasable/sell-able since it destroy the very idea why they were created (giving the creator a chance to do something with the idea before others can. If he/she/it can’t make the idea work the patent should be made null and void). Also, patents should only be applicable to physical working things – machines, gears, guts – in my opinion. The whole ‘software patent’ idea is a bit scaly if you ask me – too many blurry lines…

Perhaps it is time we/someone empty the basket so we can start ‘fresh’ again (picking fruit or something)… hehe

QuickMon 2

A quick follow-up on my QuickMon application. I’ve now managed to get a basic working application that performs some simple monitoring of 4 different types of agents (ping, file count, services and BizTalk suspended instance count). Also it includes the first notifier agent that simply logs to a plain text file.

The full architecture is a bit complicated to explain in a simple post so I’ll have to start working on a much more detail blog posting to explain it all.

Other than the documentation the next steps are to test its stability, improve error handling and adding the other basic agents I planned to make it useful.