MCTS .NET Certification Station

Covers topics on the Microsoft Certification Exam for the .NET Framework (Exam 70-536, Microsoft .NET Framework - Application Development Foundation)

Saturday, February 7, 2009

Calling unmanaged code from C#

One of the objectives of Exam 70-536 is

Implementing interoperability, reflection, and mailing functionality in a .NET Framework application
  • Call unmanaged DLL functions within a .NET Framework application, and control the marshalling of data in a .NET Framework application.
There are several subtopics in this requirement. The example presented today will cover
  • Create a class to hold DLL functions;
  • Create prototypes in managed code
  • Call a DLL function
  • Call a DLL function in special cases, such as passing structures and implementing callback functions
Many interop examples seem to cover the simplistic case of hello world in a dialog. But the real challenge when calling unmanaged code involves the marshaling data between the two memory spaces. While writing this example I had a few headaches with access violations (unmanaged code going farther than allowed) and a few marshaling errors. Everything was erroring around the lpCustColors array. In the Win32 definition it is listed as a pointer (to an array of COLORREF structures)

Rather than declare the array in managed space and marshal it over, it proved far easier to allocate and fill the array in the unmanaged space. The example below shows how to call the native ColorChooser dialog. The color chooser dialog requires a specific structure to be populated before it is called.

Calling unmanaged code from C# Example

using System;
using System.Runtime.InteropServices;

namespace InteropExample
{
public class Win32
{
[DllImport("comdlg32.dll")]
public static extern bool ChooseColor(CHOOSECOLOR pChooseColor);

[DllImport("Kernel32.dll")]
public static extern IntPtr LocalAlloc(int flags, int size);

[DllImport("Kernel32.dll")]
public static extern int LocalFree(IntPtr addr);
}

[StructLayoutAttribute(LayoutKind.Sequential)]
public class CHOOSECOLOR:IDisposable
{
public Int32 lStructSize;
public IntPtr hwndOwner;
public IntPtr hInstance;
public Int32 rgbResult;
public IntPtr lpCustColors;
public uint Flags;
public Int32 lCustData = 0;
public IntPtr lpfnHook;
public IntPtr lpTemplateName;

public CHOOSECOLOR()
{
lStructSize = System.Runtime.InteropServices.Marshal.SizeOf(this);
hwndOwner = IntPtr.Zero;
hInstance = IntPtr.Zero;
rgbResult = 0; //black
lpCustColors = Win32.LocalAlloc(64, 64);
//Fill up some random custom colors, just to show we can write to unmanaged memory
for(int i = 0; i <16; i++)
{
System.Runtime.InteropServices.Marshal.WriteInt32((IntPtr)(lpCustColors), sizeof(UInt32) * i, 0x0004937E << i);
}
Flags = 0;
lCustData = 0;
lpfnHook = IntPtr.Zero;
lpTemplateName = IntPtr.Zero;
}

public virtual void Dispose()
{
Win32.LocalFree(lpCustColors);
}
}

class Program
{
static void Main(string[] args)
{
CHOOSECOLOR chooseColorData = new CHOOSECOLOR();
Win32.ChooseColor(chooseColorData);
}
}
}


Results


Additional Resources
.NET Platform Invoke Examples (Microsoft)
Win32 ChooseColor Function (Microsoft)
Win32 Type Mapping between C++ and C# (Code Project)

Saturday, December 6, 2008

Regular Expression Vowel Counter

In this example we are going to touch on two objectives of the 70-536 exam.

Implementing globalization, drawing, and text manipulation functionality in a .NET Framework application
  • Regex class
  • MatchCollection class

Implementing serialization and input/output functionality in a .NET Framework application
  • FileStream class
  • StreamReader class
To show these classes in use we are going to count the number of vowels in 25 popular search terms (popular according to Lycos) These strings are included in a link in the resources.

Regex and File Stream Example

using System;
using System.Text.RegularExpressions;
using System.IO;

namespace SimpleRegExExample
{
class Program
{
static void Main(string[] args)
{
// In this example we are going to hit two exam points,
// using a file stream and using a regular expression.
// This example only touches on the use of regular
// expressions... in fact there are whole books on the subject
// as it can be cosidered a language it self. Feel free
// to comment on specific regular expressions you want
// to see examples on.

//Match only the vowels...
Regex vowels = new Regex("[aeiou]", RegexOptions.IgnoreCase | RegexOptions.Compiled);
MatchCollection mc;
FileStream fs = null;
StreamReader reader = null; ;
String current_line;

// A filestream can throw a number of exceptions if the file
// you use to create it can't be found or accessed ( such as
// security reasons, a disc error, etc)

try
{
// For this example we are reading in a text file with 25 lines of text.
// It's hard to make up that much data, so I just took the top 26-50
// search terms on lycos and placed them in a text file. Some of the terms
// were kind of racy, like "Kendra Wilkinson Playboy Playmate"...
// If you stumbled here hoping to find pictures of said search term, this
// is the wrong place.
fs = new FileStream("lycos_top_search_terms_26_to_50.txt",FileMode.Open);

//Life is easier when we wrap the filestream ina stream reader,
// then we don't have to code the buffering for read line operations
reader = new StreamReader(fs);
}

// This is bad, you really should catch specific exceptions...
// but we skip it for this example.
catch (Exception e)
{
Console.Out.WriteLine(e.Message);
Console.Out.WriteLine(e.StackTrace);
if (reader != null)
{
reader.Close();
}
if (fs != null)
{
fs.Close();
}
return;
}

while (!reader.EndOfStream)
{
current_line = reader.ReadLine();
mc = vowels.Matches(current_line);

// The match collect now contains the results of running the regular
// against the line we read in from the file
Console.Out.WriteLine("The search term \"" + current_line + "\" has " + mc.Count + " vowels in it");
}

//Close the reader first
reader.Close();
//Now close the file
fs.Close();
}
}
}

Output
The search term "Flickr Picture" has 4 vowels in it
The search term "Brooke Burke Dancing star" has 8 vowels in it
The search term "Kendra Wilkinson Playboy Playmate" has 10 vowels in it
The search term "Julianne Hough Watching stars" has 9 vowels in it
The search term "Twilight Vampire movie out now" has 11 vowels in it
The search term "Lindsay Lohan Relatively quiet week" has 13 vowels in it
The search term "Holly Madison Playboy Playmate #2" has 9 vowels in it
The search term "Black Friday Look for your local ad" has 11 vowels in it
The search term "Harry Potter New movie in the works" has 10 vowels in it
The search term "Weight Watchers Getting ready for the new year" has 13 vowels in it
The search term "Carmen Electra Taking it slow" has 9 vowels in it
The search term "Jessica Alba New Mom" has 7 vowels in it
The search term "Limewire Download site" has 9 vowels in it
The search term "Fox News National new coverage" has 11 vowels in it
The search term "Lowes Do-it-yourself" has 7 vowels in it
The search term "Santa Claus Coming to town" has 8 vowels in it
The search term "Beyonce Knowles Is Sasha Fierce" has 11 vowels in it
The search term "Home Depot The Lumberyard" has 8 vowels in it
The search term "Paula Abdul Leaving American Idol?" has 14 vowels in it
The search term "US Postal Service Holiday Packages " has 12 vowels in it
The search term "Jennifer Lopez Keeping it quiet" has 12 vowels in it
The search term "Haley Joel Osment On Broadway" has 10 vowels in it
The search term "Lil Wayne New CD release" has 8 vowels in it
The search term "Angelina Jolie Mom again?" has 11 vowels in it
The search term "Plentyoffish.com Dating site" has 8 vowels in it


Additional Resources
Introductions to Regular Expressions (Microsoft)
FileStream Class (Microsoft)
StreamReader Class (Microsoft)
Regular Expression Designer (Rad Software, a must have for non trivial regular expression testing)
Test File used in this example

non code related...
Lycos top 50 search terms (Lycos)

Monday, November 24, 2008

The December 21, 2012 Date Formatting Example

One of the objectives in Exam 70-536 is to ensure knowledge formatting dates. Specifically in the

Implementing globalization, drawing, and text manipulation functionality in a .NET Framework application section, we see

  • Format date and time values based on the culture

The .NET framework makes this task pretty straight forward with the System.Globalization namespace. Within this name space there is the CultureInfo class. The CultureInfo class contains all of the specific formatting rules for a specific culture. Cultures are divided up by language and region.

So to exercise this objective we print out a date in five different culture specific formats. We pick the date December 21, 2012, the end of the Mayan calendar as a fun date to use. Links are provided below about this date if you want to see what all of the buzz is about. But onto the code sample

Date Formatted Based on Culture Example

using System;
using System.Globalization;

namespace DateTimeFormatExample
{
class Program
{
static void Main(string[] args)
{
//This example is going to show how to format
// a date for several cultures. We could pick
// any date for this example, but just for kicks
// we'll pick December 21, 2012. This date is
// mysterious to astrologists and conspiracy
// theorists because it is the end of the Mayan
// calandar... will it be THE end? Who knows, but
// we'll use it here for our example.

// Declare the date December 21, 2012
DateTime dt = new DateTime(2012, 12, 21, 4, 0, 0);

//First let's print out for US English
CultureInfo en_us_ci = new CultureInfo("en-US");
//Print short date format
Console.WriteLine("US English " + dt.ToString("d", en_us_ci));

//Next let's print out for Chinese, PRC
CultureInfo zh_cn_ci = new CultureInfo("zh-CN");
Console.WriteLine("Chinese, PRC " + dt.ToString("d", zh_cn_ci));

//Next let's print out for German (Germany)
CultureInfo de_de_ci = new CultureInfo("de-DE");
Console.WriteLine("German (Germany) " + dt.ToString("d", de_de_ci));

//Next let's print out for Hebrew (Israel)
CultureInfo he_il_ci = new CultureInfo("he-IL");
Console.WriteLine("Hebrew (Israel) " + dt.ToString("d", he_il_ci));

//Next let's print out for Punjabi (India)
CultureInfo pa_in_ci = new CultureInfo("pa-IN");
Console.WriteLine("Punjabi (India) " + dt.ToString("d", pa_in_ci));
}
}
}

Date Format Example Output
US English 12/21/2012
Chinese, PRC 2012/12/21
German (Germany) 21.12.2012
Hebrew (Israel) 21/12/2012
Punjabi (India) 21-12-12

Additional Resources
CultureInfo Class (Microsoft)

Non code related...
2012 (Wikipedia)
Survive 2012

Tuesday, October 21, 2008

How do I retrieve information about the current process using C#?

I can think of many occasions when I have been diagnosing an issue on a customer machine and I find myself opening the task manager to gather valuable information about the application under question. If the customer will allow it, I will usually take the task manager one step further and use the Process Explorer from SysInternals.

But there has to be a better way, your application should be able to grab that information without using another application. And in fact it can by using the System.Diagnostics namespace. Conveniently this is also a requirement on the 70-536 exam in the "Manage system processes and monitor the performance of a .NET application by using the diagnostics functionality of the .NET Framework." section. Specifically the objective is to:

"Retrieve information about the current process"

This is made possible by the Process class within the System.Diagnostics class. Before we get into the code sample, it should be noted that a Process has a number of attributes. Many of these attributes are omitted to keep it short and sweet. Refer to the docs for the full list of Process attributes.

Current Process Info Example

using System;
using System.Diagnostics;

namespace CurrentProcessInfo
{
class Program
{
static void Main(string[] args)
{
//First lets get our parent process
Process my_process = Process.GetCurrentProcess();

// Now we'll spit out some pertinent info on our process
// Only a handful of the properties are referred to here,
// see the docs for the full list
Console.WriteLine("\nThe current process has the following attributes:");
Console.WriteLine("------------------------------------");
Console.WriteLine("Process Name: " + my_process.ProcessName);
Console.WriteLine("Window Title: " + my_process.MainWindowTitle);
Console.WriteLine("Running on: " + my_process.MachineName);
Console.WriteLine("Priority: " + my_process.PriorityClass.ToString());
Console.WriteLine("Responding: " + my_process.Responding);
Console.WriteLine("Virtual Memory: " + my_process.VirtualMemorySize64);
Console.WriteLine("------------------------------------");
}
}
}


Additional Resources
Process Class (Microsoft)
System.Diagnostics Namespace (Microsoft)

Monday, October 20, 2008

Set a break point through code with C#

If you have spent time debugging, you probably know you can click any code line to add a break point. If you have spent some more time you have probably even figured out how to set conditional breakpoints, as Sara Ford explains in this "tip of the day".

But did you know you can also cause a break point to trigger from within your code? It is actually pretty easy using the Debugger class within the System.Diagnostics name space. I learned about the Debugger class while looking over the specifics for the "Debug and trace a .NET Framework application by using the System.Diagnostics namespace." section of the 70-536 exam.

If this code is run outside of the debugger, the OS will ask you if you would like to debug the process.

Debugger Break form Code Example

using System;

namespace BreakFromCodeExample
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Thing are going fine...");
Console.WriteLine("then something goes wrong and we want to break");
Console.WriteLine("so we can investigate further...");

//This is the call that fires the break point event
System.Diagnostics.Debugger.Break();

Console.WriteLine("You are now free to place break points with or without a GUI.");
}
}
}

Additional Resources
Debugger Class (Microsoft)
System.Diagnostics Namespace (Microsoft)

Implemeting the IConfigurationSystem Interface

After a long hiatus... getting back in the writing zone....

Within the "Embedding configuration, diagnostic, management, and installation features into a .NET Framework application" section of Exam 70-536 we are instructed to "Implement IConfigurationSystem Interface".

This seemed like a fairly straight forward task so I immediately looked up the interface in the MSDN docs. However, upon reading about the interface, I think someone goofed. The documentation specifically says that the IConfigurationSystem Interface "
supports the .NET Framework infrastructure and is not intended to be used directly from your code."

So maybe we don't need to know too much about this interface after all. Just in case the error is on the side of the documentation, you need to implement two methods to support the IConfigurationSystem Interface
  • GetConfig
  • Init

GetConfig returns an object and takes configKey (String) as a parameter.
Init returns void and takes no parameters.

Additional Resources
IConfigurationSystem Interface (Microsoft)

Saturday, May 24, 2008

How Do You Retrieve Information About All Network Connections?

One of the objectives of the MCTS .NET Framework exam is to

Embed management information and events into a .NET Framework application. (Refer System.Management namespace)

and within that exam objective there is the specific objective

Retrieve information about all network connections.

I started to look through the System.Management namespace and found the ManagementObject and the ManagementObjectSearcher. Then the clarity of the examples of the descriptions and examples began to muddy. I understood that the ManagementObjectSearcher was using an ObjectQuery object to perform the search. It was completely unclear WHAT was being queried.

My investigations then lead me to the Windows Management Interface, known as WMI. What does this have to do with ObjectQuery and the ManagementObjectSearcher classes? Well, WMI and the underlying WMI classes are what is actually being queried. The queries are written in a SQL derivative named WQL. There is a dizzying variety of information exposed by WMI.

After the mechanics of writing a query are understood, the next task is to find the correct WMI class that encapsulates the information you need. In the case of our question at hand, we are looking for networking information.

At first I was happy to find the Win32_NetworkConnection class, but found that it did not return information for me. (Despite having a connection up for writing this post). The next promising class was the Win32_NetworkAdapter class. Using this class I created the example below that retrieves information about all network connections.

A "gotcha" to consider before reviewing the code below:
My first version of the code listed a number of adapters. I then determined that it listed physical AND logical network adapters. You will see an if block in the code to distinguish between physical and logical adapters.

Retrieve Information About All Network Connections Example

using System;
// A reference to the System.Management assembly needs
// to be added to your project...
using System.Management;

namespace NetworkConnectionsExample
{
class Program
{
static void Main(string[] args)
{
// In order to use ManagementObjectSearcher, we need to
// supply an query string to search on. We are searching
// against differenct classes exposed by the Windows Management
// Interface(WMI).
ManagementObjectSearcher network_connections =
new ManagementObjectSearcher(
"SELECT * FROM Win32_NetworkAdapter");

Console.WriteLine("\nFirst we will just list the names of all physical adapters");
Console.WriteLine("and their connection status");
Console.WriteLine("-----------------------------");

// The query of the underlying ObjectQuery object is not executed
// until the Get() function is executed.
foreach (ManagementObject connection in network_connections.Get())
{
// Knowledge by experiment... on my machine there were a number
// of network adapters displayed on my first version of this code.
// I know I only have three pyhisical adapters (Wireless, 10/100,
// and 1394) so I empirically determined that the Management Objects
// with the NetConnectionStatus property were physical apdapters and
// not logical adapters... mileage may vary, results not insured ;)
if (connection.Properties["NetConnectionStatus"].Value != null)
{
Console.WriteLine("Product Name: " + connection.Properties["ProductName"].Value);
Console.WriteLine("Connection Status: " + connection.Properties["NetConnectionStatus"].Value);
Console.WriteLine("-----------------------------");
}
}

Console.WriteLine("\nNext we will show all of the information availalbe for each physical adapter.");
Console.WriteLine("Probably more than you ever wanted to know about your network adapter, but your software might need to know it...");
Console.WriteLine("-----------------------------");

foreach (ManagementObject connection in network_connections.Get())
{
if (connection.Properties["NetConnectionStatus"].Value != null)
{
foreach (PropertyData d in connection.Properties)
{
Console.WriteLine("-- Name: " + d.Name + " Value: " + d.Value);
}
Console.WriteLine("-----------------------------");
}
}
}
}
}

Additional Resources
ManagementObjectSearcher class (Microsoft)
WMI Operating System Classes (Microsoft)
Win32_NetworkAdapter class (Microsoft)

Support This Site

LinkShare  Referral  Prg