Friday, June 3, 2011

Determine Windows Version and Edition with C#

This article explains how to use C# to determine the name, edition, service pack, version and bits of the host operating system.
For example, the results on my PC would be:
Operation System Information
—————————-
Name = Windows Vista
Edition = Home Premium
Service Pack = Service Pack 1
Version = 6.0.6001.65536
Bits = 64
Sample Program
Here is a simple console program that demonstrates this:

using System;

namespace CSharp411
{
class Program
{
static void Main( string[] args )
{
Console.WriteLine( "Operation System Information" );
Console.WriteLine( "----------------------------" );
Console.WriteLine( "Name = {0}", OSInfo.Name );
Console.WriteLine( "Edition = {0}", OSInfo.Edition );
Console.WriteLine( "Service Pack = {0}", OSInfo.ServicePack );
Console.WriteLine( "Version = {0}", OSInfo.VersionString );
Console.WriteLine( "Bits = {0}", OSInfo.Bits );
Console.ReadLine();
}
}
}

Show ToolTip on TabPage in TabControl

So you’ve set the ToolTipText property of a TabPage in a TabControl. When the user moves the mouse pointer over the tab, the text you specified is supposed to show in a tooltip.


But what if the tooltip is not showing? Fortunately, this problem has an easy solution:

Set the ShowToolTips property in the TabControl to true.

Cosing all forms in an application

Cosing all forms in an application seems like it would be a simple task of using a foreach loop in the Application.OpenForms collection, such as:

foreach (Form form in Application.OpenForms)
{
form.Close();


But there are two problems.
First, the code above will throw an exception because the OpenForms collection changes each time you close a form, and so the enumerator in your foreach loop becomes invalid when you close a form. Instead, you need to get an array of all open forms, then loop through the array:
static public void CloseAllForms()
{
// get array because collection changes as we close forms
Form[] forms = OpenForms;

// close every open form
foreach (Form form in forms)
{
CloseForm( form );
}
}


Second, it’s quite possible that your application opened one or more forms in a separate thread. If so, then trying to close a form from your main thread will throw an exception. So you need to close your forms in a thread-safe manner:

delegate void CloseMethod( Form form );
static private void CloseForm( Form form )
{
if (!form.IsDisposed)
{
if (form.InvokeRequired)
{
CloseMethod method = new CloseMethod( CloseForm );
form.Invoke( method, new object[] { form } );
}
else
{
form.Close();
}
}
}

Rename a File in C#

If you want to rename a file in C#, you’d expect there to be a File.Rename method, but instead you must use the System.IO.File.Move method.
You must also handle a special case when the new file name has the same letters but with difference case. For example, if you want to rename “test.doc” to “Test.doc”, the File.Move method will throw an exception. So you must rename it to a temp file, then rename it again with the desired case.


///
/// Renames the specified file.
///

/// Full path of file to rename.
/// New file name.
static public void RenameFile( string oldPath, string newName )
{
if (String.IsNullOrEmpty( oldPath ))
throw new ArgumentNullException( "oldPath" );
if (String.IsNullOrEmpty( newName ))
throw new ArgumentNullException( "newName" );

string oldName = Path.GetFileName( oldPath );

// if the file name is changed
if (!String.Equals( oldName, newName, StringComparison.CurrentCulture ))
{
string folder = Path.GetDirectoryName( oldPath );
string newPath = Path.Combine( folder, newName );
bool changeCase = String.Equals( oldName, newName, StringComparison.CurrentCultureIgnoreCase );

// if renamed file already exists and not just changing case
if (File.Exists( newPath ) && !changeCase)
{
throw new IOException( String.Format( "File already exists:\n{0}", newPath ) );
}
else if (changeCase)
{
// Move fails when changing case, so need to perform two moves
string tempPath = Path.Combine( folder, Guid.NewGuid().ToString() );
Directory.Move( oldPath, tempPath );
Directory.Move( tempPath, newPath );
}
else
{
Directory.Move( oldPath, newPath );
}
}
}