Friday, March 14, 2008

Creating screenshot with C#

We all know that debugging application or finding errors from 'word of mouth' from end users can be pain, event if you have some complex logging mechanism (like log4net) in your application. For Windows Forms application sometimes the best 'view' on what happened in complex forms/controls may be screenshot of how application looks at the moment errors occurs.

In my Winforms applications I have a small routine attached on 'error reporting handler' that process exception and display error info form every time exception occurs. This small routine will create screenshot every time exception occurs, save screenshot to temp directory and attach it to the e-mail sent to me. E-mail also includes full exception details, but as I said in some cases screenshot of users desktop may be priceless ;)

Enough words:

using System.Drawing; using System.Drawing.Imaging;

private static Bitmap GetScreenShot() { Rectangle bounds = Screen.PrimaryScreen.Bounds; int colourDepth = Screen.PrimaryScreen.BitsPerPixel; PixelFormat format; switch (colourDepth) { case 8: case 16: format = PixelFormat.Format16bppRgb565; break;

case 24: format = PixelFormat.Format24bppRgb; break;

case 32: format = PixelFormat.Format32bppArgb; break;

default: format = PixelFormat.Format32bppArgb; break; } Bitmap captured = new Bitmap(bounds.Width, bounds.Height, format); Graphics gdi = Graphics.FromImage(captured); gdi.CopyFromScreen(bounds.Left, bounds.Top, 0, 0, bounds.Size); return captured; }

Then you can simply save Bitmap from this method to temp directory, very simple example:

using System.IO;

string screenShotFile = null; try { // get screenshot Bitmap screenShot = GetScreenShot(); screenShotFile = string.Format("{0}{1}", Path.GetTempPath(), "screen.jpg"); screenShot.Save(screenShotFile, ImageFormat.Jpeg); } catch (Exception screenEx) { // unable to retrieve/save bitmap screenShotFile = null; }

With this, you can simply attach file with screenshot to the logging mechanism/e-mail etc. Let me know if it helps you ;)

Wednesday, March 5, 2008

C# Universal Type Converter

using System; using System.Collections.Generic; using System.Text; namespace UniversalTypeConverter { class Program { static void Main(string[] args) { Obj obj = new Obj(); obj["Name"] = "Joe"; obj["Age"] = 27; obj["StartDate"] = new DateTime(2002, 9, 8); Write(obj); obj["Name"] = "Mike"; obj["Age"] = 34; obj["StartDate"] = new DateTime(2005, 12, 5); Write(obj); Console.ReadLine(); } static void Write(Obj obj) { string name = obj["Name"]; int age = obj["Age"]; DateTime startDate = obj["StartDate"]; Console.WriteLine("name={0} age={1} start={2:d}", name, age, startDate); } } public class Obj { Dictionary m_PropValues = new Dictionary(); public PropValue this[string name] { get { PropValue prop = null; m_PropValues.TryGetValue(name, out prop); return prop; } set { if (m_PropValues.ContainsKey(name)) { m_PropValues[name] = value; } else { PropValue prop = value; m_PropValues.Add(name, prop); } } } } public class PropValue { private object m_Value; public object Value { get { return m_Value; } } public PropValue(object val) { m_Value = val; } public static implicit operator PropValue(int val) { return new PropValue(val); } public static implicit operator PropValue(string val) { return new PropValue(val); } public static implicit operator PropValue(DateTime val) { return new PropValue(val); } public static implicit operator int(PropValue prop) { return (prop.Value as int?) ?? -1; } public static implicit operator string(PropValue prop) { return (prop.Value as string) ?? string.Empty; } public static implicit operator DateTime(PropValue prop) { return (prop.Value as DateTime?) ?? DateTime.MinValue; } } }