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

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)

Thursday, May 22, 2008

How can I read an EventLog?

Perhaps you have a need to read from a system event log. Perhaps you have even found the System.Diagnostics namespace. Upon inspecting the EventLog class you will notice a "Write" method but the absence of a complimentary "Read" operation. You are not going crazy, there really isn't a read method.

Instead you need to understand a little more about the EventLog object. The entire contents of an EventLog are read in when the EventLog is constructed (if the variant with a logname is used) or when the Log property is set for the object. The results of reading the event log are stored in the Entries property. The entries property is a collection of EventLogEntry objects. If you would like to see the contents of a particular EventLogEntry, you need "massage" the object a little more by accessing specific properties of the EventLogEntry class.

It is important to note that the Entries property is a read only property. You can't change the contents of the event log by modifying the Entries property. In order to change the event log, you need to use the "Write" methods.

The example below shows how to access the 10 most recent log entries from the System event log.

System Event Log Read Example

using System;
using System.Collections.Generic;
using System.Text;
using System.Diagnostics;

namespace ReadEventLogExample
{
class Program
{
static void Main(string[] args)
{
// There are three default event logs, Application, System and Security
EventLog systemLog = new EventLog("System");
// The entries member contains all the entries in the event log
// There is no need to perform a specific read operation on the event log
// The Entries member is read only, so you will need to use the write
// methods if you want to write to the EventLog
int entryCount = systemLog.Entries.Count;
entryCount = entryCount - 1; //We are using the count for a zero based index...

Console.WriteLine("The last 10 entries in the System event log");

for (int i = 0; i < 10; i++)
{
if (entryCount - i >= 0) //We only want positive indexes...
{
Console.WriteLine("------------------------------------\n");
Console.WriteLine("Time Generated: " + systemLog.Entries[entryCount - i].TimeGenerated);
Console.WriteLine("Time Written: " + systemLog.Entries[entryCount - i].TimeWritten);
Console.WriteLine("Source: " + systemLog.Entries[entryCount - i].Source);
Console.WriteLine("Entry Type: " + systemLog.Entries[entryCount - i].EntryType);
Console.WriteLine("Message: " + systemLog.Entries[entryCount - i].Message + "\n");
}
}
}
}
}

Additional Resources
EventLog Class (Microsoft)
EventLogEntry Class (Microsoft)

What is the difference between byte and Byte in the .NET Framework?

Have you ever started to type 'by' while writing code in Visual Studio and seen both an upper case and lower case "byte" in the intellisense menu and wondered what the difference was?

Lower case "byte" is a built in type in C#. System.Byte is a class built into the .NET framework that represents a byte. The secret is that this built in type is an alias to the System.Byte class. Different .NET languages have different aliases based on the semantics of the particular language, but they all map to specific object types in the .NET framework. This allows code to be written more "cleanly" and still easily compile to the correct type in the .NET framework.

Let's confirm the statement that the C# built in type 'byte' is really an alias of the System.Byte class.

byte and System.Byte Example

using System;
using System.Collections.Generic;
using System.Text;

namespace ByteDifferenceExample
{
class Program
{
static void Main(string[] args)
{
byte small_b_byte = 1;
Byte large_b_byte = 2;

Console.WriteLine("The value of the little b byte is: " + small_b_byte);
Console.WriteLine("The type of the little b byte is: " + small_b_byte.GetType());

Console.WriteLine("----------------------------");

Console.WriteLine("The value of the big b byte is: " + large_b_byte);
Console.WriteLine("The type of the big b byte is: " + large_b_byte.GetType());

Console.WriteLine("----------------------------");

if (small_b_byte.GetType() == large_b_byte.GetType())
{
Console.WriteLine("Summary: byte and Byte have the same type!");
}
else
{
Console.WriteLine("Summary: byte and Byte have different types");
}
}
}
}

Output of byte and System.Byte Example

The value of the little b byte is: 1
The type of the little b byte is: System.Byte
----------------------------
The value of the big b byte is: 2
The type of the big b byte is: System.Byte
----------------------------
Summary: byte and Byte have the same type!

Additional Resources
Built-In Types Table, C# (Microsoft)

Monday, May 19, 2008

What is a stack good for?

A stack is a specialized list data structure that enforces LIFO (last in, first out) ordering of data. Thinking of a stack as a physical stack of plates (and data items as the plates), you can only take the last plate that you added to the stack.

The stack data structure is among the most useful structures in Computer Science. Stack usage appears at all levels of programming, from operating system kernels to high level languages like those in the .NET framework. Saying that a stack is useful is easy to say, but let's look at some tasks that a stack can be used for:

Stack Usage Examples

In a future posting a detailed example that uses a stack will be provided.

Additional Resources
System.Collections.Stack Class (Microsoft)
Stacks (Wikipedia)

Support This Site

LinkShare  Referral  Prg