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.

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!