Capture an Image of the Desktop, Specific Screen or Portion of a Screen with C#

So today is my birthday. It has been a wild ride this last 46 years. Lets hope that things continue to get better.

So this is my entire class for capturing screens and desktop appearance to an image file or to print them. I use this class quite often in my error management, saving or emailing the output should errors occur so I can get a good idea of what was going on at the time an error occurs. Why? Because often end users or business analysts, though they are trying their best, sometimes can’t describe in detail how to reproduce what occurred. I suggest using this in conjunction with a logging class as well so that you can replicate the steps needed. The image file is also very handy in reconstructing what a user was or was not doing which, as a coder, can literally save your ass on occasion. So here it is. It is well commented and pretty straight forward.

using System.Windows.Forms;
using System;
using System.Runtime.InteropServices;
using System.Drawing;
using System.Drawing.Imaging;

public class clsScreenCapture
{
    private System.Drawing.Printing.PrintDocument Pd = new System.Drawing.Printing.PrintDocument();
    private PictureBox PicForm = new PictureBox();

    /// Creates an Image object containing a screen shot of the entire desktop
    public Image CaptureScreen()
    {
        return CaptureWindow(User32.GetDesktopWindow());
    } //CaptureScreen
    /// Creates an Image object containing a screen shot of a specific window
    public Image CaptureWindow(IntPtr handle)
    {
        int SRCCOPY = 0xCC0020;
        // get te hDC of the target window
        IntPtr hdcSrc = User32.GetWindowDC(handle);
        // get the size
        User32.RECT windowRect = new User32.RECT();
        User32.GetWindowRect(handle, ref windowRect);
        int width = windowRect.right – windowRect.left;
        int height = windowRect.bottom – windowRect.top;
        // create a device context we can copy to
        IntPtr hdcDest = GDI32.CreateCompatibleDC(hdcSrc);
        // create a bitmap we can copy it to,
        // using GetDeviceCaps to get the width/height
        IntPtr hBitmap = GDI32.CreateCompatibleBitmap(hdcSrc, width, height);
        // select the bitmap object
        IntPtr hOld = GDI32.SelectObject(hdcDest, hBitmap);
        // bitblt over
        GDI32.BitBlt(hdcDest, 0, 0, width, height, hdcSrc, 0, 0, SRCCOPY);
        // restore selection
        GDI32.SelectObject(hdcDest, hOld);
        // clean up
        GDI32.DeleteDC(hdcDest);
        User32.ReleaseDC(handle, hdcSrc);

        // get a .NET image object for it
        Image img = Image.FromHbitmap(hBitmap);
        // free up the Bitmap object
        GDI32.DeleteObject(hBitmap);

        return img;
    } //CaptureWindow
    /// Captures a screen shot of a specific window, and saves it to a file
    public void CaptureWindowToFile(IntPtr handle, string filename, ImageFormat format)
    {
        Image img = CaptureWindow(handle);
        img.Save(filename, format);
    } //CaptureWindowToFile
    /// Captures a screen shot of a specific window, and saves it to a file
    public void CaptureWindowToPrinter(Form mfForm, ImageFormat format)
    {
        // Dim img As Image = CaptureScreen()

        Image img = CaptureWindow(mfForm.Handle);
        try
        {
            PicForm.Image = img;
            if (MessageBox.Show(“Press Yes to Print or No to Copy to your Clipboard (‘No’ will allow pasting into an email or Word document etc).”, “Print or Copy to Clipboard?”, MessageBoxButtons.YesNo) == DialogResult.Yes)
            {
                Pd.Print();
            }
            else
            {
                Clipboard.SetDataObject(img, true);
            }
        }
        catch (Exception ex)
        {
            string a = “vfdgsfg”;
        }
    } //CaptureWindowToPrinter
    private void pd_PrintPage(object sender, System.Drawing.Printing.PrintPageEventArgs e)
    {
        //—————————————————————
        // this procedure handles events raised by the printer object pd
        //—————————————————————
        e.Graphics.DrawImageUnscaled(PicForm.Image, 0, 0); //send image to printer – upper left position

        e.HasMorePages = false; //this is the last page to print

    }

    /// Captures a screen shot of the entire desktop, and saves it to a file
    public void CaptureScreenToFile(string filename, ImageFormat format)
    {
        Image img = CaptureScreen();
        img.Save(filename, format);
    } //CaptureScreenToFile
    public Bitmap CaptureDeskTopRectangle(Rectangle CapRect, int CapRectWidth, int CapRectHeight)
    {
        /// Returns BitMap of the region of the desktop, similar to CaptureWindow, but can be used to
        /// create a snapshot of the desktop when no handle is present, by passing in a rectangle
        /// Grabs snapshot of entire desktop, then crops it using the passed in rectangle’s coordinates
        clsScreenCapture SC = new clsScreenCapture();
        Bitmap bmpImage = new Bitmap(SC.CaptureScreen());
        Bitmap bmpCrop = new Bitmap(CapRectWidth, CapRectHeight, bmpImage.PixelFormat);
        Rectangle recCrop = new Rectangle(CapRect.X, CapRect.Y, CapRectWidth, CapRectHeight);
        Graphics gphCrop = Graphics.FromImage(bmpCrop);
        Rectangle recDest = new Rectangle(0, 0, CapRectWidth, CapRectHeight);
        gphCrop.DrawImage(bmpImage, recDest, recCrop.X, recCrop.Y, recCrop.Width, recCrop.Height, GraphicsUnit.Pixel);
        return bmpCrop;
    }
    /// Helper class containing Gdi32 API functions
    private class GDI32
    {
        public int SRCCOPY = 0xCC0020;
        // BitBlt dwRop parameter
        [System.Runtime.InteropServices.DllImport(“gdi32.dll”, EntryPoint=”BitBlt”, ExactSpelling=true, CharSet=System.Runtime.InteropServices.CharSet.Ansi, SetLastError=true)]
        public static extern Int32 BitBlt(IntPtr hDestDC, Int32 x, Int32 y, Int32 nWidth, Int32 nHeight, IntPtr hSrcDC, Int32 xSrc, Int32 ySrc, Int32 dwRop);

        [System.Runtime.InteropServices.DllImport(“gdi32.dll”, EntryPoint=”CreateCompatibleBitmap”, ExactSpelling=true, CharSet=System.Runtime.InteropServices.CharSet.Ansi, SetLastError=true)]
        public static extern IntPtr CreateCompatibleBitmap(IntPtr hdc, Int32 nWidth, Int32 nHeight);

        [System.Runtime.InteropServices.DllImport(“gdi32.dll”, EntryPoint=”CreateCompatibleDC”, ExactSpelling=true, CharSet=System.Runtime.InteropServices.CharSet.Ansi, SetLastError=true)]
        public static extern IntPtr CreateCompatibleDC(IntPtr hdc);

        [System.Runtime.InteropServices.DllImport(“gdi32.dll”, EntryPoint=”DeleteDC”, ExactSpelling=true, CharSet=System.Runtime.InteropServices.CharSet.Ansi, SetLastError=true)]
        public static extern Int32 DeleteDC(IntPtr hdc);

        [System.Runtime.InteropServices.DllImport(“gdi32.dll”, EntryPoint=”DeleteObject”, ExactSpelling=true, CharSet=System.Runtime.InteropServices.CharSet.Ansi, SetLastError=true)]
        public static extern Int32 DeleteObject(IntPtr hObject);

        [System.Runtime.InteropServices.DllImport(“gdi32.dll”, EntryPoint=”SelectObject”, ExactSpelling=true, CharSet=System.Runtime.InteropServices.CharSet.Ansi, SetLastError=true)]
        public static extern IntPtr SelectObject(IntPtr hdc, IntPtr hObject);
    } //GDI32
    /// Helper class containing User32 API functions
    public class User32
    {
        [StructLayout(LayoutKind.Sequential)]
        public struct RECT
        {
            public int left;
            public int top;
            public int right;
            public int bottom;
        } //RECT

        [System.Runtime.InteropServices.DllImport(“user32.dll”, EntryPoint=”GetDesktopWindow”, ExactSpelling=true, CharSet=System.Runtime.InteropServices.CharSet.Ansi, SetLastError=true)]
        public static extern IntPtr GetDesktopWindow();

        [System.Runtime.InteropServices.DllImport(“user32.dll”, EntryPoint=”GetWindowDC”, ExactSpelling=true, CharSet=System.Runtime.InteropServices.CharSet.Ansi, SetLastError=true)]
        public static extern IntPtr GetWindowDC(IntPtr hwnd);

        [System.Runtime.InteropServices.DllImport(“user32.dll”, EntryPoint=”ReleaseDC”, ExactSpelling=true, CharSet=System.Runtime.InteropServices.CharSet.Ansi, SetLastError=true)]
        public static extern Int32 ReleaseDC(IntPtr hwnd, IntPtr hdc);

        [System.Runtime.InteropServices.DllImport(“user32.dll”, EntryPoint=”GetWindowRect”, ExactSpelling=true, CharSet=System.Runtime.InteropServices.CharSet.Ansi, SetLastError=true)]
        public static extern Int32 GetWindowRect(IntPtr hwnd, ref RECT lpRect);

    } //User32

    public clsScreenCapture()
    {
        SubscribeToEvents();
    }

// event handler wireups:
    private bool EventsSubscribed = false;
    private void SubscribeToEvents()
    {
        if (EventsSubscribed)
            return;
        else
            EventsSubscribed = true;

        Pd.PrintPage += pd_PrintPage;
    }

}


Join me on Facebook

, , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , ,

Leave a comment

Encryption and Decryption of strings with C#

Well I am checking out the Beale Street Historic District for the first time in Memphis, TN tonight. I have heard a lot about it since my arrival here so am excited to get to go. I think it will be fun.

Of course this would come up. I had written this previously in vb.net and I had the opportunity to use it again today. Of course in doing so, I discovered a bad coding practice violation I had committed. I had failed to return a value in my function’s Catch block of my code. C# doesn’t let you off the hook so easily and will bug you till you fix it. As noted previously, topic is encryption and decryption of strings. It is straightforward but you might find it useful. Simply pass in the string you want to encrypt/decrypt and the key you want to use.

using System;
using System.IO;
using System.Text;
using System.Security.Cryptography;
public class Crypto
{
    private static TripleDESCryptoServiceProvider DES = new TripleDESCryptoServiceProvider();
    private static MD5CryptoServiceProvider MD5 = new MD5CryptoServiceProvider();
    public static byte[] MD5Hash(string value)
    {
        return MD5.ComputeHash(ASCIIEncoding.ASCII.GetBytes(value));
    }
    public static string Encrypt(string stringToEncrypt, string key)
    {
        DES.Key = Crypto.MD5Hash(key);
        DES.Mode = CipherMode.ECB;
        byte[] Buffer = ASCIIEncoding.ASCII.GetBytes(stringToEncrypt);
        return Convert.ToBase64String(DES.CreateEncryptor().TransformFinalBlock(Buffer, 0, Buffer.Length));
    }
    public static string Decrypt(string encryptedString, string key)
    {
        try
        {
            DES.Key = Crypto.MD5Hash(key);
            DES.Mode = CipherMode.ECB;
            byte[] Buffer = Convert.FromBase64String(encryptedString);
            return ASCIIEncoding.ASCII.GetString(DES.CreateDecryptor().TransformFinalBlock(Buffer, 0, Buffer.Length));
        }
        catch (Exception ex)
        {
            MessageBox.Show(“Invalid Key”, “Decryption Failed”, MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
        }
// Inserted the following ‘return’ since all code paths must return a value in C#:
        return null;
    }
}

And now it’s usage…..

public class Form1
{
    private void Button1_Click(object sender, System.EventArgs e)
    {
        string key = Microsoft.VisualBasic.Interaction.InputBox(“Enter a Key:”, “”, “”, -1, -1);
        Label1.Text = Crypto.Encrypt(TextBox1.Text, key);
        TextBox1.Clear();
    }
    private void Button2_Click(object sender, System.EventArgs e)
    {
        string key = Microsoft.VisualBasic.Interaction.InputBox(“Enter a Key:”, “”, “”, -1, -1);
        TextBox1.Text = Crypto.Decrypt(Label1.Text, key);
    }

    }


Join me on Facebook

, , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , ,

2 Comments

Save Control Settings with vb.net

What’s this you say? A new blog entry? If you haven’t completely deserted me …. well I don’t know what’s wrong with you! Smile jk. But anyway here is the latest. I am working for a national hotel chain in Memphis, TN. I got married, moved to New Jersey and am we are now separated. Yes it is a long story and no I am not going to bore you with the details!

Before I go any further, I actually write very little in vb.net anymore. The language is awesome. It’s just that very few people want that skill set now and if you want to be employed you need to write in C#. It’s just the way it is. However in this particular task, I found vb.net to be the tool of choice here. The reason is there is no C# equivalent to VB’s implicit ‘once only’ variable initialization within loops. I am not sure why that is but that is the case here. This code snippet is ideal when you want to allow the end user to dictate how a given control is to look or operate. Yes in my example I am using an Infragistic control so if you copy and paste this do NOT email me complaining about broken references please! I hope you find the code useful and thank you for showing up! Smile

Public Shared Sub SaveControl(ByVal StateName As String, ByVal ParamArray Controls As Control())
        Dim section As String = “”
        Dim appName As String = StringType.FromObject(Interaction.IIf((StringType.StrCmp(Application.ProductName, “”, False) = 0), “VSDesigner”, Application.ProductName))
        Dim control As Control
        For Each control In Controls
            If (Not control.FindForm Is Nothing) Then
                Dim form As Form
                If (StringType.StrCmp((StateName & “”), “”, False) > 0) Then
                    section = String.Concat(New String() { control.FindForm.Name, “.”, control.Name, “.”, StateName })
                Else
                    section = (control.FindForm.Name & “.” & control.Name)
                End If
                If TypeOf control Is Form Then
                    form = DirectCast(control, Form)
                    If (form.WindowState = FormWindowState.Normal) Then
                        Interaction.SaveSetting(appName, form.Name, “Top”, StringType.FromInteger(form.Top))
                        Interaction.SaveSetting(appName, form.Name, “Left”, StringType.FromInteger(form.Left))
                        Interaction.SaveSetting(appName, form.Name, “Height”, StringType.FromInteger(form.Height))
                        Interaction.SaveSetting(appName, form.Name, “Width”, StringType.FromInteger(form.Width))
                    End If
                    Interaction.SaveSetting(appName, form.Name, “WindowState”, StringType.FromInteger(CInt(form.WindowState)))
                ElseIf TypeOf control Is Splitter Then
                    form = control.FindForm
                    Dim splitter As Splitter = DirectCast(control, Splitter)
                    Interaction.SaveSetting(appName, section, “SplitPosition”, StringType.FromInteger(splitter.SplitPosition))
                ElseIf TypeOf control Is FilterListView Then
                    Dim view2 As FilterListView = DirectCast(control, FilterListView)
                    form = view2.FindForm
                    Interaction.SaveSetting(appName, section, “View”, StringType.FromInteger(CInt(view2.ListView.View)))
                    Dim header As ColumnHeader
                    For Each header In view2.ListView.Columns
                        Interaction.SaveSetting(appName, section, (“Column” & StringType.FromInteger(header.Index)), StringType.FromInteger(header.Width))
                    Next
                    Dim filter As FilterListViewFilter
                    For Each filter In view2.Filters
                        Dim tag As UserProfileSetting
                        If (filter.Tag Is Nothing) Then
                            tag = Context.User.Settings.NewItem
                            Dim setting2 As UserProfileSetting = tag
                            setting2.Type = UserProfileSettingTypeEnum.FilterListView
                            setting2.Name = section
                            setting2.Description = filter.Name
                            setting2.Value = filter.Filter
                            setting2 = Nothing
                            filter.Tag = tag
                        ElseIf filter.Deleted Then
                            tag = DirectCast(filter.Tag, UserProfileSetting)
                            If Context.User.Settings.Contains(tag) Then
                                Context.User.Settings.Remove(tag)
                            End If
                        Else
                            tag = DirectCast(filter.Tag, UserProfileSetting)
                            tag.Value = filter.Filter
                        End If
                    Next
                    Context.User.Settings.Save
                ElseIf (TypeOf control Is ListView Or TypeOf control Is SortListView) Then
                    form = control.FindForm
                    Dim view As ListView = DirectCast(control, ListView)
                    Interaction.SaveSetting(appName, section, “View”, StringType.FromInteger(CInt(view.View)))
                    Dim header As ColumnHeader
                    For Each header In view.Columns
                        Interaction.SaveSetting(appName, section, (“Column” & StringType.FromInteger(header.Index)), StringType.FromInteger(header.Width))
                    Next
                ElseIf TypeOf control Is TabControl Then
                    form = control.FindForm
                    Dim control2 As TabControl = DirectCast(control, TabControl)
                    Interaction.SaveSetting(appName, section, “View”, StringType.FromInteger(control2.SelectedIndex))
                ElseIf TypeOf control Is TextBox Then
                    form = control.FindForm
                    Dim box3 As TextBox = DirectCast(control, TextBox)
                    Interaction.SaveSetting(appName, section, “Text”, box3.Text)
                ElseIf TypeOf control Is ComboBox Then
                    form = control.FindForm
                    Dim box As ComboBox = DirectCast(control, ComboBox)
                    If (box.DropDownStyle = ComboBoxStyle.DropDown) Then
                        Interaction.SaveSetting(appName, section, “Text”, box.Text)
                    End If
                    Interaction.SaveSetting(appName, section, “SelectedIndex”, StringType.FromInteger(box.SelectedIndex))
                ElseIf TypeOf control Is CheckBox Then
                    form = control.FindForm
                    Dim box2 As CheckBox = DirectCast(control, CheckBox)
                    Interaction.SaveSetting(appName, section, “Checked”, StringType.FromBoolean(box2.Checked))
                ElseIf TypeOf control Is DataGrid Then
                    form = control.FindForm
                    Dim grid As DataGrid = DirectCast(control, DataGrid)
                    Dim num As Integer = 0
                    Dim style As DataGridTableStyle
                    For Each style In grid.TableStyles
                        Dim num2 As Integer = 0
                        Dim style2 As DataGridColumnStyle
                        For Each style2 In style.GridColumnStyles
                            Interaction.SaveSetting(appName, (section & StringType.FromInteger(num) & “.” & StringType.FromInteger(num2)), “Width”, StringType.FromInteger(style2.Width))
                            num2 += 1
                        Next
                        num += 1
                    Next
                ElseIf TypeOf control Is KeyedDropDown Then
                    form = control.FindForm
                    Dim down As KeyedDropDown = DirectCast(control, KeyedDropDown)
                    If (down.DropDownStyle = ComboBoxStyle.DropDown) Then
                        Interaction.SaveSetting(appName, section, “Text”, down.Text)
                    End If
                    Interaction.SaveSetting(appName, section, “SelectedIndex”, StringType.FromInteger(down.SelectedIndex))
                ElseIf TypeOf control Is UltraGrid Then
                    Dim grid2 As UltraGrid = DirectCast(control, UltraGrid)
                    Dim enumerator2 As BandEnumerator = grid2.DisplayLayout.Bands.GetEnumerator
                    Do While enumerator2.MoveNext
                        Dim current As UltraGridBand = enumerator2.Current
                        Dim enumerator As ColumnEnumerator = current.Columns.GetEnumerator
                        Do While enumerator.MoveNext
                            Dim column As UltraGridColumn = enumerator.Current
                            Interaction.SaveSetting(appName, section, (“Hidden.” & StringType.FromInteger(current.Index) & “.” & column.Key), StringType.FromBoolean(column.Hidden))
                            Interaction.SaveSetting(appName, section, (“Width.” & StringType.FromInteger(current.Index) & “.” & column.Key), StringType.FromInteger(column.Width))
                        Loop
                    Loop
                End If
            End If
        Next
    End Sub

Facebook

, , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , ,

Leave a comment

Get CPU Usage of a Process using C#

This was a fun assignment. I was asked to write a piece of code that when a particular process id was passed to it it would return its CPU usage. WMI is fun. Have a great night….

public static decimal GetUssage(string pid)
{
//get the process
ManagementObjectSearcher searcher = new ManagementObjectSearcher(“SELECT * FROM Win32_Process WHERE ProcessID = ” + pid);
decimal PercentProcessorTime = 0;
foreach (ManagementObject queryObj in searcher.Get())
{
DateTime firstSample, secondSample;

//populate the process info
firstSample = DateTime.Now;
queryObj.Get();
//get cpu usage
ulong u_oldCPU = (ulong)queryObj.Properties[“UserModeTime”].Value
+ (ulong)queryObj.Properties[“KernelModeTime”].Value;
//sleep to create interval
System.Threading.Thread.Sleep(1000);
//refresh object
secondSample = DateTime.Now;
queryObj.Get();
//get new usage
ulong u_newCPU = (ulong)queryObj.Properties[“UserModeTime”].Value
+ (ulong)queryObj.Properties[“KernelModeTime”].Value;

decimal msPassed = (decimal)(secondSample – firstSample).TotalMilliseconds;

//formula to get CPU ussage
if (u_newCPU > u_oldCPU)
PercentProcessorTime = (decimal)((u_newCPU – u_oldCPU)
/ (msPassed * 100 * Environment.ProcessorCount));

Console.WriteLine(“processor time ” + PercentProcessorTime);
}
return PercentProcessorTime;
}

, , , ,

Leave a comment

How to make Linq and IList sort Dynamically using C#

I apologize that it has been a while. I have been extremely busy and in the time that I have been away I went through treatment for a medical issue. Needless to say I had other issues to deal with other than this blog. But I will try to publish more frequently. Today’s topic was a question from another developer which was to have have a Linq and IList sort dynamically. So long as you don’t force execution by using ToList, you can keep tacking on to your query until you are ready to actually run it. This is because much of LINQ uses “deferred execution”. For example, you could do something similar to:

var query = apps.AsQueryable()
.Select
(Application => new
{
ID = Application.ApplicationId,
Force = Application.Force.Description,
Function = Application.BusinessFunction.Description,
Category = Application.Category.Description,
SubCategory = Application.SubCategory.Description,
Name = Application.ApplicationName,
Description = Application.ApplicationDescription
}
).Take(10);

switch (sortType)
{
case “ID”:
query = query.Orderby(Application => Application.ApplicationId);
break;
case “Force”:
query = query.Orderby(Application => Application.Force);
break;
}

IList tempList = query.ToList();

As always it has been great getting your all feedback while I was gone. Thank You! Smile

, , , , , , , , , , , , , , , , , , , , , , , , ,

Leave a comment

Follow

Get every new post delivered to your Inbox.