C# – Logging to the Windows Event Viewer

In the past for any applications I’ve written in C#, I’ve always logged any information I needed to in a .txt file in the Windows %temp% directory. This was really quite a messy approach when I consider it now.

Logging from your applications can be useful for a couple of reasons:

  • Auditing: Depending on your level of logging, you can get a step by step view of what’s happening with your application. I find this useful for testing as I write code.
  • Diagnostics: This is the more obvious use of logging from your application – capturing a stack trace or other useful information in the event of any issues.

Using the Windows Event Viewer to capture auditing or diagnostic logging is a much better approach, as you can specify when you log what type of event this is, i.e. ‘Information’ (for auditing), or ‘Warning’ and ‘Error’ (for diagnostic logging). This makes it a lot easier to find errors, and makes any logging you do highly readable.

I’ve created this class which wraps the logging to the Event Viewer functionality:


using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Diagnostics;

namespace EventLoggingExample
{
public class LoggingHelper
{
private string Application;
private string EventLogName;

///

/// Constructor
///

/// The application doing the logging /// The log to write to in the Event Viewer public LoggingHelper(string app, string log)
{
Application = app;
EventLogName = log;

// Create the event log if it doesn't exist
if (!EventLog.SourceExists(Application))
{
EventLog.CreateEventSource(Application, EventLogName);
}

}

///

/// Write to the event log
///

/// The message to write public void WriteToEventLog(string message, string type)
{
switch (type.ToUpper())
{
case "INFO":
EventLog.WriteEntry(Application, message, EventLogEntryType.Information);
break;
case "ERROR":
EventLog.WriteEntry(Application, message, EventLogEntryType.Error);
break;
case "WARN":
EventLog.WriteEntry(Application, message, EventLogEntryType.Warning);
break;
default:
EventLog.WriteEntry(Application, message, EventLogEntryType.Information);
break;
}
}
}
}

To use it, just create an instance and log at will:


LoggingHelper log = new LoggingHelper("MyApplication", "MyAppLog");
log.WriteToEventLog("Some application information", "info");
log.WriteToEventLog("This is your first warning!", "warn");
log.WriteToEventLog("An error has occurred...", "error");

This is definetely something I’ll be adding to my utilities library.

Windows Phone 7 – Check if first run

Many of the applications I’ve been looking at developing during my Windows Phone 7 endeavours have a common requirement – the ability to check if this is the first run of the application. For example, if you are designing an application that will access a service like Twitter or Facebook, you’ll need to gather the users login details in order for your application to function.

For example, on the first run of the application, we’ll want to display a login dialog, gather the users information and store it. We can use the isolated storage facility on Windows Phone 7 devices to store this information. If you’re unfamiliar with isolated storage, check out my previous post here.

Step 1 – Store a value to track if this is the first run

I added this code to the ‘Application_Launching’ function. This function is called each time your application is launched.


// Code to execute when the application is launching (eg, from Start)
// This code will not execute when the application is reactivated
private void Application_Launching(object sender, LaunchingEventArgs e)
{
// Set if this is the first run of the application or not
if (!settings.Contains("firstRun"))
{
settings.Add("firstRun", (bool)true);
}
else
{
settings["firstRun"] = (bool)false;
}
}

Step 2 – Intercept navigation to your main page, redirect if necessery

Next, we need to create an event handler to intercept any navigation the your main page, and redirect to your ‘first run’ page (login or whatever) if necessery.

First we check if we’re navigating to our main page, if we’re not the function just returns and navigation proceeds as normal. If we are, we’ll ensure that if it’s the first run of the application, the user will be redirected to a login page etc.


///

/// Event handler to intercept MainPage navigation
///

/// the frame /// navigation args void RootFrame_Navigating(object sender, NavigatingCancelEventArgs e)
{
// Only care about MainPage
if (e.Uri.ToString().Contains("/MainPage.xaml") != true)
{
return;
}

// Check if this is the first run of the application
if ((bool)settings["firstRun"])
{
e.Cancel = true;
RootFrame.Dispatcher.BeginInvoke(delegate
{
RootFrame.Navigate(new Uri("/FirstRun.xaml", UriKind.Relative));
settings["firstRun"] = (bool)false;
});
}
else
{
RootFrame.Dispatcher.BeginInvoke(delegate
{
RootFrame.Navigate(new Uri("/MainPage.xaml", UriKind.Relative));
});
}
}

Step 3 – Ensure the event handler is called when navigation occurs

Finally, we need ensure that the event handler we created in step 2 above is actually called when any navigation occurs. To accomplish this, all we need to do is add the following code in the constructor of the ‘App.xaml.cs’ file:

// Add this code to the constructor in App.xaml.cs

// Route the user to the login screen if it's the first run of the application
RootFrame.Navigating += new NavigatingCancelEventHandler(RootFrame_Navigating);

That’s pretty much it, I’ve successfully used the above mechanism in two different applications, hope this saves you some time!

ASP.NET MVC – Creating a DropDownList

I’ve been looking at the ASP.NET MVC framework for the past two weeks, and it has occurred to me that some of the simple things we may want to do when creating a web application may seem confusing to someone new to ASP.NET MVC – for example the task of creating a DropDownList control on a form. ASP.NET MVC provides a number of ‘HTML Helpers’ which we can easily use to construct the form items. ‘DropDownList’ is one of these HTML helpers we can use.

Let’s create a simple example form using some of these HTML helpers. To begin a form, we can use a helper, we just need to add this code to our View:


<% using (Html.BeginForm()){ %>

// Form data will go here

<% } %>

This creates the basic form code for us – no need to explicitly write any HTML code. Before adding the DropDownList control, we need to decide where we want to get the data which will bind to the list. We can either hard code the items, or use LINQ to SQL to grab them from a database at runtime.

Method 1 – Hardcoding the form items

With this approach, we just add the items to a list, and pass this list to ViewData, so we can access it from the View:


List items = new List();
items.Add(new SelectListItem
{
Text = "Apple",
Value = "1"
});
items.Add(new SelectListItem
{
Text = "Banana",
Value = "2",
Selected = true
});
items.Add(new SelectListItem
{
Text = "Orange",
Value = "3"
});

ViewData["DDLItems"] = items;
return ViewData;

Then, to actually display the DropDownList, we’d just need to add a single line to our View code, utilizing the DropDownList HTML helper:


<%= Html.DropDownList("DDLItems") %>

Method 2 – Using LINQ to SQL to get the data at runtime

We could also retrieve the list data from a database table at runtime using LINQ to SQL. In order for this approach to work, you will need to have generated LINQ to SQL classes for your database using the wizard in Visual Studio. Then we can easily write the code to retrieve the data:


// Get the list of supported languages (for example) from the DB
var db = new TransDBDataContext();
IEnumerable languages = db.trans_SupportedLanguages
.Select(c => new SelectListItem
{
Value = Convert.ToString(c.ID),
Text = c.Name.ToString()
});

ViewData["SupportedLanguages"] = languages;
return View();

Again, to display the DropDownList, we’d just need to add a single line of code to the View:


<%= Html.DropDownList("SupportedLanguages") %>

From the above, you can see how easy it is to render form items using the HTML helpers provided by ASP.NET MVC.

For a full list of the helpers, check out the MSDN documentation here.

Windows Phone 7 – Storing & Retrieving Information

I’m planning on doing a series of posts called ‘2 Minute Tutorials’. I always get frustrated when searching for information on the Internet. Sometimes, I just want a simple explanation, and a code example that I can utilize immediately. This is what I hope to provide in this series of posts, which will be mostly related to Windows Phone 7, C#, and C++.

In this particular installment, I’m going to take you through the process of storing and retrieving information on the Windows Phone 7 platform – a certain requirment should you intend developing a WP7 application. You can store information on the phones local file system quite easily. This may be required for saving such things as user information like usernames and passwords to services such as Twitter, or application specific preferences such as a preferred language or orientation.

This functionality is provided by the IsolatedStorageSettings class contained in the System.IO.IsolatedStorage namespace. It’s ‘isolated’, because it can only be accessed by your application, not by any others. If you need to share information between applications, you’ll need to store it on the web somewhere – this offers local, isolated storage only.

IsolatedStorageSettings allows you to store name/value pairs in a dictionary. This data will always be there, even after powering off the phone. It will remain in the file system until you either remove it, or you uninstall the application to which it belongs.

Here’s an example of storing an item called ‘username’:

using System.IO.IsolatedStorage;
...
IsolatedStorageSettings settings = IsolatedStorageSettings.ApplicationSettings;
settings.Add("username", "jimmy");

Simple. It’s just as easy to retrieve the data again:

string username = (string) settings['username'];

Some important things to remember:

  • Your application will throw an exception if you try to retrieve a value that is not present so you should always handle this case.
  • You can save anything, even Objects.
  • You have to explicitly cast your data when you retrieve it.

That’s it. It’s that simple to store and retrieve information on the local file system of a device running Windows Phone 7.

See here for the MSDN documention on IsolatedStorageSettings.

Windows Phone 7 Development – First Impressions

Since my Christmas leave from work has begun, I’ve had some time to really look at Windows Phone 7 development over the last 2 days, and have gotten really excited about it all. I’ve been meaning to do this for ages (since WP7 was released actually), but have always either been too busy or suffered procrastination (thanks Zen Habits!).

Some positives:

  • Development Environment – I think Microsoft has done an excellent job on Visual Studio 2010, and the WP7 development tools plug in seamlessly. If you don’t already have Visual Studio 2010, Microsoft is offering a special Express Editon for Windows Phone.
  • Developer Resources – There are a huge amount of resources available on Microsoft’s App Hub (often called ‘MarketPlace’ – the equivalent of Apple’s ‘App Store’), ranging from tutorials, walkthroughs of some key concepts and full application code examples.
  • The Windows Phone Emulator – This is installed as part of the developer tools, and it really is state of the art. I haven’t purchased an actual device running WP7, but have been using the emulator to test my inital application effort. There are some obvious things that won’t work on the emulator, for example anything to do with the accellerometers (the emulator assumes it is lying on a flat surface), but it’s perfect for testing your inital Windows Phone 7 applications.
  • Familiarity – If you’ve ever developed using C# on the Windows platform, you already have a huge start in WP7 development.
  • Developer Subscription – The cost of a yearly developers subscription, a mere 99 Euro, can easily be covered with very little downloads of your applications (should you even be bothered about it).

The only ‘negative’ I’ve found so far is that I’ve had to purchase a (long overdue) brand new Dell running Windows 7 in order to create my development environment. My previous machine, running Windows XP, is not supported by the Windows Phone 7 development tools, which seems strange to me, since XP is not scheduled to be EOL’d until 2014. It seems to be another move by Microsoft to push people to move to Windows 7 or (shudder) Windows Vista.

Windows Phone 7 development is one of the three areas I want to become proficient with in the first half of 2011. I had initially focused on the iOS platform, but when I thought about it, it didn’t make much sense, since I’m already familiar with C# and didn’t feel I’d gain any real advantage by learning Objective C. Also, rumours began to circulate this week regarding Microsoft getting into bed with Nokia, so WP7 will surely gain more momentum in the first half of 2011.

My first application, (well under way!), will be a simple Twitter client. The reason I chose this is that it will encompass many of the key concepts I’ll need to learn, such as designing user interfaces for WP7, storing information locally on a WP7 device, and accessing external information via API’s. I plan to complete this over Christmas – screenshots to follow once it is.

Aside: If you’re interested in getting into developing on the Windows Phone 7 platform, check out Jeff Blankenburg’s 31 Days of Windows Phone, it’s the best introductory article series I’ve found so far.

C# – Using Bing’s Translation Web Service

Microsoft’s Bing Translator provides a translation web service which can be called via C#. In this post I’ll outline the steps to use this web service, and create a simple application to perform translations.

First, you’ll need to create a valid application ID for your application. This is required in order to be able to call the web service. Head over to Bing’s Developer Centre and sign in with your Windows Live ID. Follow the steps to create a new ID for your application, it’s a simple process and shouldn’t take you any more than 2 minutes.

Next, create a new project in Visual Studio, (I’ve created a simple Windows forms application to demonstrate this, but you could just as easily create a simple console application). You’ll need to add a service reference to your application either way. Do this by right-clicking on your solution and selecting ‘Add Service Reference’. Under ‘Address’, add this:

http://api.microsofttranslator.com/V1/SOAP.svc

Under ‘namespace’, be sure to enter a descriptive name for the service reference. Now, for the code to perform translations (You’ll need to add in the application ID you created earlier in order for this to work):

// Translating from English to German

string textToTranslate = "Hello, world";
string sourceLanguage = "en";
string targetLanguage = "de"
string translatedText = "";

try
{
BingTranslatorService.LanguageServiceClient client = new BingTranslatorService.LanguageServiceClient();
translatedText = client.Translate("Your App ID", textToTranslate, sourceLanguage, targetLanguage);
MessageBox.Show(translatedText);
}
catch (Exception ex)
{
MessageBox.Show("An error has occurred: " + ex.ToString(), "Error");
}

‘BingTranslatorService’ above is whatever you called the service reference added earlier. I’ve created this sample application to show how easy it is to create a simple translation application:

Simple Translation Application

Download the full source code, here. You’ll need to add in your application ID in order for this to work properly.

Localization of C# Applications – Short Introduction

If you plan on releasing your C# application in non-English speaking markets, you will obviously want the UI to display localized strings. When developing applications using .NET, it’s relatively simple to achieve this. In this post, I’ll outline the steps involved in localizing a simple C# application.

.NET applications store string resources in .resx files. These are XML format, with the main advantage being they are human readable and can be opened in any text editor, unlike resource DLL files for example. The only item not human readable in a .resx file, may be an embedded object, like a Bitmap file for example.

Start off by creating a simple Windows Forms application from Visual Studio, it will create an initial form for us to work on.  Select the form and on the ‘Properties’ dialog look for the ‘Localizable’ property and set it to ‘true’. You may also notice the ‘Language’ property, leave this set to ‘Default’ for the moment.

Next, add a button to the form and add some text to it, something simple, for example:

Simple Localizable Form

If you take a look under your form in ‘Solution Explorer’, you will notice a .resx file has been created. It will be named FormName.resx, open this up and search for the string on your button and you will see how it is stored. Now to add the equivalent German strings (or any other language you fancy!).

Recall the forms ‘Language’ property mentioned earlier, you will find it under ‘Properties’ when you’ve got the form selected. In the dropdown, change the value to ‘German’. You will not notice any visible changes, but you can now edit the strings on the form to represent the German equivalents. Do this for as many languages as you want to. Once you’ve done this, take a look under your form in ‘Solution Explorer’, you will notice that a new .resx file has been added automatically, FormName.de.resx. This will contain your German strings. You should note here that you can also change the layout of the form to include any required changes, in the event some strings are longer in certain languages, e.g. Greek.

Now when your application is run on a German operating system, the strings displayed will be automatically taken from FormName.de.resx, rather than FormName.resx.

A note about locale selection

The UI language used in Windows is a function of the CurrentUICulture setting. In order to see the German strings actually display, you would need to install a German language pack, and change your regional settings, or we could just set our locale programmatically in our application.

In order to test your German strings display correctly, first add the following imports:

using System.Globalization;
using System.Threading;

Then add the following code to your form initialization function, (before InitializeComponent()):

// Sets the UI culture to German (Germany).
Thread.CurrentThread.CurrentUICulture = new CultureInfo("de");

This will make our application believe it’s running on a German locale. Now run your application, you should see your German strings displayed:

German Strings Displayed

This post outlined the very basics of localizing .NET applications. In future posts, I plan on expanding this a bit to advanced topics such as avoiding common internationalization issues.

Retrieve settings from COM+ components via C#

Recently, I had a requirement to be able to retrieve settings information from a number of COM+ components running on a server, such as the Constructor String etc. The idea behind this was to give us a snapshot of a servers configuration, and also allow easy comparisons between different servers in the event of issues. This is tedious and time consuming to do manually, especially if you’ve got a large number of components within each COM+ application, so I resolved to write a small C# program to do this for me and write the data to a file.

COM+ provides an administration object model that exposes all of the functionality of the Component Services administrative tool, so by adding a reference to the necessary library, you can achieve anything you can do through the graphical administrative tool, programmatically. To get started, you’ll need to add a reference to the necessary library – ‘COM + 1.0 Admin Type Library’. This can be found under the ‘COM’ tab when you go to add a reference to your project in Visual Studio.

You’ll need to add the following import also:


using COMAdmin;

First, we’ll need to create an Object to store the catalog of COM+ components installed on the machine. Here’s the code to create this catalog, and also retrieve a list of all the COM+ applications it contains:


COMAdminCatalog catalog;
COMAdminCatalogCollection applications;

// Get the catalog
catalog = new COMAdminCatalog();

// Get the list of all COM+ applications contained within this catalog
applications = (COMAdminCatalogCollection)catalog.GetCollection("Applications");
applications.Populate();

Now we have an Object above, ‘applications’, which contains all the data regarding what COM+ applications are installed on this machine. To go a little deeper, and see which components each application contains, it’s just as easy:


foreach (COMAdminCatalogObject application in applications)
{
COMAdminCatalogCollection components;
components = (COMAdminCatalogCollection)
components = (COMAdminCatalogCollection)applications.GetCollection ("Components", Application.Key);
components.Populate();

foreach (COMAdminCatalogObject component in components)
{
Console.WriteLine("Component: " + component.Name);
}
}

The above code shows you how to get a list of COM+ applications and their components, but what about retrieving or setting the values of specific component settings like the Constructor String of a component?

Here’s how:


// Set the value of a constructor string
component.set_Value("ConstructorString", "127.0.0.1");
// Get the value of a constructor string
component.get_Value("ConstructorString"));

That’s a quick overview, I leave it as an exercise to the reader to explore the other functionality of the ‘COMAdmin’ library, but if you just need to retrieve values of settings from specific components, the above will get you started.

As per normal, MSDN has some great documentation here.

LINQ to XML – What I’ve been missing

Ok. You may laugh. I’ve just today used LINQ for the first time to parse an XML file, and I’m seriously blown away at how easy it was. I’m a little embarrassed, since LINQ has been available since .NET 3.5 was released around November 2007.

If you are like I was, (LINQ-less!!), I’ll give a brief introduction here. LINQ (Language INtegrated Query), is a component that adds native data querying capabilities to .NET languages. It can be used to read, parse and write XML files (and also SQL, which I may cover in a future post). Take a look at the example below to see how easy it is to use this technique to read data from an XML file.

Reading data from an XML file is a very common scenario. I always used .ini file as configuration files for any applications I wrote, but .NET doesn’t provide any built in support for .ini, and hence wants you to use XML.

Consider the following XML file:

In order to read this using LINQ to XML, you need to ensure you have specifed the correct header files:


using System.Linq;
using System.Xml.Linq;

Now for the easy part, here’s the code to read data from the XML file, and print out the values to the console:


XDocument xmlDoc = XDocument.Load(@"example.xml");
var servers = from server in xmlDoc.Descendants("server")
select new
{
     Name = server.Element("name").Value,
     IP = server.Element("ip").Value,
     Owner = server.Element("owner").Value,
};


foreach (var server in servers)
{
     Console.WriteLine("Server Name: " + server.Name);
     Console.WriteLine("Server IP: " + server.IP);
     Console.WriteLine("Server Owner: " + server.Owner);
}

Easy huh? The line beginning with ‘var servers=…‘ may look strange to you if you’ve never seen it before, (it did to me). This is an anonymous type declaration. If you’ve never heard of anonymous types in C#, MSDN has some great documentation here.

Happy coding.

The poor mans OCR

Optical Character Recognition (OCR) has been around a long time. One of it’s main uses, for those not familiar, is to gather text from images.

Off the shelf products, such as Abby’s FineReader exist, with prices ranging from $150 for a single user copy, to up to $10000 for large enterprise ‘site licenses’. But where’s the fun in buying it!

I learnt recently that Microsoft Office 2007 has built in OCR capabilities which can be accessed from C# via a COM interface. I will explain in this post how to leverage these capabilites.

First off, you need to have MS Office 2007 installed. This is obviously a dependency if you develop an application to use the OCR capabilites in the field – it won’t work without Office installed. Furthermore, the OCR capability doesn’t install by default when you install Office, you need to add a component called ‘Microsoft Office Document Imaging’ (MODI).

For instructions on how to add the required component, look here.

Now that you have MODI installed, you can create an OCR application! Boot up Visual Studio and create a new C# console application.

You’ll first need to add a reference to MODI, so we can use it from your application. From the Visual Studio Solution Explorer window, right-click on the ‘References’ folder. When the dialog box appears, select the ‘COM’ tab. Finally, select the object named ‘Microsoft Office Document Imaging 12.0 Type Library’.

The code below will create a new MODI document, retrieve the text, and ouput it word by word to the console, (you could also output it to a text file or a custom XML file, I leave that as an exercise for the reader). I’ve assumed below the image file you wish to retrieve the text from is located at ‘C:\Images’.


// Grab the text from an image
MODI.Document md = new MODI.Document();
md.Create(@"C:\Images\Image.tif");
md.OCR(MODI.MiLANGUAGES.miLANG_ENGLISH, true, true);

// Retrieve the text gathered from the image
MODI.Image image = (MODI.Image)md.Images[0];
MODI.Layout layout = image.Layout;

// Loop through the list of words
for (int j = 0; j < layout.Words.Count; j++) { MODI.Word word = (MODI.Word)layout.Words[j]; Console.WriteLine(word.Text); } md.Close(false);

Notice the 'MODI.MiLANGUAGES.miLANG_ENGLISH' parameter above, this is set to the language you are dealing with. It looks like 22 languages are supported, including Japanese and the Chinese variants.

When I ran this, (using the home page of my McAfee 'Total Protection' 2010 suite as the guinea pig), the results were surprisingly accurate (for English anyway), with only two recognition errors.

Take a look here.

I wonder if it is also as accurate for double byte languages like Japanese etc. I'd also like to check it against an RTL language like Arabic.

Anyway, it's definetely worth a look if you want to develop a custom OCR application on a shoestring budget.

Programmatically verify resources in a DLL

I had a requirement recently to be able to programmatically check certain resources were contained in a set of (native) DLL resource files. The idea behind this was to add some post-build automated engineering checks to our existing automated test suite, e.g. ensuring resources for all the required languages have been injected correctly.

I wanted to write a simple C# application to perform these checks. I came accross this handy library which contained functions for almost all the functionality I required:

ResourcesLib

Using this, we can perform functions such as importing resources, loading strings, and even injecting new resources.

For example, here’s how you could retrieve all languages contained in a resource DLL:

string file = "resource.dll";
RawResourceFile resFile = new RawResourceFile();
resFile.Load(file);

for (int i = 0; i < resFile.Languages.Count; i++) { Console.WriteLine("Language: " + resFile.Languages[i]); }

Download the library and take a look, it can save you lots of time if you need to perform any checks/actions on DLL file.

Automating Virtual Machine operations on ESXi Server from C#

VMware provides two really useful API’s for automating virtual machine (VM) tasks on both VMware Workstation and VMware ESXi server.

  • VI Infrastructure API
  • VIX API

These are extremely easy to use from C#. In a QA environment, the automation of VM’s can be hugely benifical, wheather attempting to automate an environment for build sanity checks or functional tests.

This post will outline the basics of using the VIX API from C#, in order to perform operations on VMware ESXi server. If you don’t have access to an ESXi server, you can install it on a VM, it’s free to download from the VMware website!

For starters, you will need to install the API’s on your development machine. In order to download, you will need to create a VMware account, which you may already have if you have downloaded Workstation or ESXi server in the past. If you dont, you can create an account for free. Once logged into your account, you can download both API’s from the ‘Support & Downloads’ section.

Let me explain the differance between these two API’s. From VMware’s own documentation:

The VI API provides access to the VMware Infrastructure management components—the managed objects that can be used to manage, monitor, and control life-cycle operations of virtual machines and other VMware infrastructure components (datacenters, datastores, networks, and so on).”

VIX on the other hand, is used to automate the actual operations on VM’s, such as booting them, copying in files, getting/setting VM environment varibles and other tasks you may wish to perform. The coolest part of VIX is that a wrapper for C# exists, created by Daniel Doubrovkine over at dblock.org. This wrapper, ‘VMwareTasks’, provides a simple object-orientated approach to VIX, which will be familar to C# developers. Download the wrapper here.

Now for the basics of using the VIX API and VMwareTasks wrapper. Create a new console application project in Visual Studio. You will need to add a reference to the VMwareTasks DLL, which is located in the ‘bin’ directory when you extract the VMwareTasks download.

Look how simple it is to power on a VM!


// Declare a new virtual host
VMWareVirtualHost host = new VMWareVirtualHost();

// Connect to the ESXi server
host.ConnectToVMWareVIServer("192.168.1.39", "root", "password123");

// Power on an existing VM by name
VMWareVirtualMachine machine = host.Open("[datastore1] XPP_SP2.vmx");
machine.PowerOn();

The simple code above just connects to an ESXi server, and powers on an existing VM, but you can see how easy it is to perform operations on VM’s.

Here’s how to create and revert to a snapshot:


VMWareVirtualHost host = new VMWareVirtualHost();
host.ConnectToVMWareVIServer("192.168.1.39", "root", "password123");
VMWareVirtualMachine machine = host.Open("[datastore1] Vista_EN.vmx");
machine.PowerOn();
machine.Login("Tester", "testing");

string snapShotName = "base";
machine.Snapshots.CreateSnapshot(snapShotName, "Clean");
machine.PowerOff();

VMWareSnapshot snapshot = machine.Snapshots.GetNamedSnapshot("base");
snapshot.RevertToSnapshot();

Or to create a directory:


machine.CreateDirectoryInGuest(@"C:\TestDir");

You can see from the above examples how easy it is to perform operations on VM’s using these API’s. Install the API’s and play around with the functionality, I guarantee you’ll be impressed!