
Visual CSharp 2005 Recipes (2006) [eng]
.pdf
498C H A P T E R 1 3 ■ C O M M O N LY U S E D I N T E R FA C E S A N D PAT T E R N S
//Loop, getting temperature readings from the user.
//Any noninteger value will terminate the loop.
do
{
Console.WriteLine(Environment.NewLine); Console.Write("Enter current temperature: ");
try
{
//Convert the user's input to an integer and use it to set
//the current temperature of the Thermostat. t.Temperature = Int32.Parse(Console.ReadLine());
}
catch (Exception)
{
//Use the exception condition to trigger termination. Console.WriteLine("Terminating Observer Pattern Example.");
//Wait to continue. Console.WriteLine(Environment.NewLine); Console.WriteLine("Main method complete. Press Enter"); Console.ReadLine();
return;
}
} while (true);
}
}
}
Usage
The following listing shows the kind of output you should expect if you build and run the previous example. The bold values show your input.
Enter current temperature: 50
ChangeObserver: Old=0, New=50, Change=50
AverageObserver: Average=50.00
Enter current temperature: 20
ChangeObserver: Old=50, New=20, Change=-30
AverageObserver: Average=35.00
Enter current temperature: 40
ChangeObserver: Old=20, New=40, Change=20
AverageObserver: Average=36.67


500 C H A P T E R 1 4 ■ W I N D O W S I N T E G R AT I O N
Table 14-1. Commonly Used Members of the Environment Class
Member |
Description |
Properties |
|
CommandLine |
Gets a string containing the command line used to execute the |
|
current application, including the application name; see recipe 1-5 |
|
for details. |
CurrentDirectory |
Gets and sets a string containing the current application |
|
directory. Initially, this property will contain the name of the |
|
directory in which the application was started. |
HasShutdownStarted |
Gets a bool that indicates whether the CLR has started to shut |
|
down or the current application domain has started unloading. |
MachineName |
Gets a string containing the name of the machine. |
OSVersion |
Gets a System.OperatingSystem object that contains information |
|
about the platform and version of the underlying operating |
|
system. See the paragraph following this table for more details. |
ProcessorCount |
Gets the number of processors on the machine. |
SystemDirectory |
Gets a string containing the fully qualified path of the system |
|
directory, that is, the system32 subdirectory of the Windows |
|
installation folder. |
TickCount |
Gets an int representing the number of milliseconds that have |
|
elapsed since the system was started. |
UserDomainName |
Gets a string containing the Windows domain name to which the |
|
current user belongs. This will be the same as MachineName if the user |
|
has logged in on a machine account instead of a domain account. |
UserInteractive |
Gets a bool indicating whether the application is running in user |
|
interactive mode; in other words, its forms and message boxes |
|
will be visible to the logged-on user. UserInteractive will return |
|
false when the application is running as a service or is a Web |
|
application. |
UserName |
Gets a string containing the name of the user that started the |
|
current thread, which can be different from the logged-on user in |
|
case of impersonation. |
Version |
Gets a System.Version object that contains information about the |
|
version of the CLR. |
Methods |
|
ExpandEnvironmentVariables |
Replaces the names of environment variables in a string with the |
|
value of the variable; see recipe 14-2 for details. |
GetCommandLineArgs |
Returns a string array containing all elements of the command |
|
line used to execute the current application, including the |
|
application name; see recipe 1-5 for details. |
GetEnvironmentVariable |
Returns a string containing the value of a specified environment |
|
variable; see recipe 14-2 for details. |
GetEnvironmentVariables |
Returns an object implementing System.Collections.IDictionary, |
|
which contains all environment variables and their values; see |
|
recipe 14-2 for details. |

C H A P T E R 1 4 ■ W I N D O W S I N T E G R AT I O N |
501 |
Member |
Description |
GetFolderPath |
Returns a string containing the path to a special system folder |
|
specified using the System.Environment.SpecialFolder |
|
enumeration. This includes folders for the Internet cache, |
|
cookies, history, desktop, and favorites; see the .NET Framework |
|
SDK documentation for a complete list of values. |
GetLogicalDrives |
Returns a string array containing the names of all logical drives, |
|
including network mapped drives. Note that each drive has the |
|
following syntax: <drive letter>:\. |
|
|
The System.OperatingSystem object returned by OSVersion contains four properties:.
•The Platform property returns a value of the System.PlatformID enumeration identifying the current operating system; valid values are Unix, Win32NT, Win32S, Win32Windows, and WinCE.
•The ServicePack property returns a string identifying the service pack level installed on the computer. If no service packs are installed, or service packs are not supported, an empty string is returned.
•The Version property returns a System.Version object that identifies the specific operating system version.
•The VersionString property returns concatenated string summary of the Platform, ServicePack, and Version properties.
To determine the operating system on which you are running, you must use both the platform and the version information as detailed in Table 14-2.
Table 14-2. Determining the Current Operating System
PlatformID |
Major Version |
Minor Version |
Operating System |
Win32Windows |
4 |
10 |
Windows 98 |
Win32Windows |
4 |
90 |
Windows ME |
Win32NT |
4 |
0 |
Windows NT 4 |
Win32NT |
5 |
0 |
Windows 2000 |
Win32NT |
5 |
1 |
Windows XP |
Win32NT |
5 |
2 |
Windows Server 2003 |
|
|
|
|
The Code
The following example uses the Environment class to display information about the current environment to the console:
using System;
namespace Apress.VisualCSharpRecipes.Chapter14
{
class Recipe14_01
{
public static void Main()
{
// Command line.
Console.WriteLine("Command line : " + Environment.CommandLine);

502C H A P T E R 1 4 ■ W I N D O W S I N T E G R AT I O N
//OS and CLR version information. Console.WriteLine(Environment.NewLine); Console.WriteLine("OS PlatformID : " + Environment.OSVersion.Platform); Console.WriteLine("OS Major Version : " +
Environment.OSVersion.Version.Major); Console.WriteLine("OS Minor Version : " + Environment.OSVersion.Version.Minor);
Console.WriteLine("CLR Version : " + Environment.Version);
//User, machine, and domain name information. Console.WriteLine(Environment.NewLine); Console.WriteLine("User Name : " + Environment.UserName);
Console.WriteLine("Domain Name : " + Environment.UserDomainName); Console.WriteLine("Machine name : " + Environment.MachineName);
//Other environment information. Console.WriteLine(Environment.NewLine); Console.WriteLine("Is interactive? : "
+Environment.UserInteractive);
Console.WriteLine("Shutting down? : "
+Environment.HasShutdownStarted); Console.WriteLine("Ticks since startup : "
+Environment.TickCount);
//Display the names of all logical drives. Console.WriteLine(Environment.NewLine);
foreach (string s in Environment.GetLogicalDrives())
{
Console.WriteLine("Logical drive : " + s);
}
//Standard folder information. Console.WriteLine(Environment.NewLine); Console.WriteLine("Current folder : "
+Environment.CurrentDirectory); Console.WriteLine("System folder : "
+Environment.SystemDirectory);
//Enumerate all special folders and display them. Console.WriteLine(Environment.NewLine);
foreach (Environment.SpecialFolder s in Enum.GetValues(typeof(Environment.SpecialFolder)))
{
Console.WriteLine("{0} folder : {1}", s, Environment.GetFolderPath(s));
}
//Wait to continue. Console.WriteLine(Environment.NewLine); Console.WriteLine("Main method complete. Press Enter."); Console.ReadLine();
}
}
}

C H A P T E R 1 4 ■ W I N D O W S I N T E G R AT I O N |
503 |
14-2. Retrieve the Value of an Environment Variable
Problem
You need to retrieve the value of an environment variable for use in your application.
Solution
Use the GetEnvironmentVariable, GetEnvironmentVariables, and ExpandEnvironmentVariables methods of the Environment class.
How It Works
The GetEnvironmentVariable method allows you to retrieve a string containing the value of a single named environment variable, whereas the GetEnvironmentVariables method returns an object implementing IDictionary that contains the names and values of all environment variables as strings. The .NET Framework 2.0 introduces an additional overload of the GetEnvironmentVariables method that takes a System.EnvironmentVariableTarget argument, allowing you to specify a subset of environment variables to return based on the target of the variable: Machine, Process, or User.
The ExpandEnvironmentVariables method provides a simple mechanism for substituting the value of an environment variable into a string by including the variable name enclosed in percent signs (%) within the string.
The Code
Here is an example that demonstrates how to use all three methods:
using System;
using System.Collections;
namespace Apress.VisualCSharpRecipes.Chapter14
{
class Recipe14_02
{
public static void Main()
{
//Retrieve a named environment variable. Console.WriteLine("Path = " +
Environment.GetEnvironmentVariable("Path"));
Console.WriteLine(Environment.NewLine);
//Substitute the value of named environment variables. Console.WriteLine(Environment.ExpandEnvironmentVariables( "The Path on %computername% is %Path%"));
Console.WriteLine(Environment.NewLine);
//Retrieve all environment variables targeted at the process and
//display the values of all that begin with the letter U. IDictionary vars = Environment.GetEnvironmentVariables(
EnvironmentVariableTarget.Process);

504 C H A P T E R 1 4 ■ W I N D O W S I N T E G R AT I O N
foreach (string s in vars.Keys)
{
if (s.ToUpper().StartsWith("U"))
{
Console.WriteLine(s + " = " + vars[s]);
}
}
// Wait to continue. Console.WriteLine(Environment.NewLine); Console.WriteLine("Main method complete. Press Enter."); Console.ReadLine();
}
}
}
14-3. Write an Event to the Windows Event Log
Problem
You need to write an event to the Windows event log.
Solution
Use the members of the System.Diagnostics.EventLog class to create a log (if required), register an event source, and write events.
How It Works
You can write to the Windows event log using the static methods of the EventLog class, or you can create an EventLog object and use its members. Whichever approach you choose, before writing to the event log you must decide which log you will use and register an event source against that log. The event source is simply a string that uniquely identifies your application. An event source may be registered against only one log at a time.
By default, the event log contains three separate logs: Application, System, and Security. Usually, you will write to the Application log, but you might decide your application warrants a custom log in which to write events. You do not need to explicitly create a custom log; when you register an event source against a log, if the specified log doesn’t exist, it’s created automatically.
Once you have decided on the destination log and registered an event source, you can start to write event log entries using the WriteEntry method. WriteEntry provides a variety of overloads that allow you to specify some or all of the following values:
•A string containing the event source for the log entry (static versions of WriteEntry only).
•A string containing the message for the log entry.
•A value from the System.Diagnostics.EventLogEntryType enumeration, which identifies the type of log entry. Valid values are Error, FailureAudit, Information, SuccessAudit, and Warning.
•An int that specifies an application-specific event ID for the log entry.
•A short that specifies an application-specific subcategory for the log entry.
•A byte array containing any raw data to associate with the log entry.


506 C H A P T E R 1 4 ■ W I N D O W S I N T E G R AT I O N
Solution
Use the methods GetValue and SetValue of the Microsoft.Win32.Registry class.
■Tip The GetValue and SetValue methods open a registry key, get or set its value, and close the key each time they are called. This means they are inefficient when used to perform many read or write operations. The GetValue and SetValue methods of the Microsoft.Win32.RegistryKey class discussed in recipe 14-5 will provide better performance if you need to perform many read or write operations on the registry.
How It Works
The GetValue and SetValue methods (new to .NET 2.0) allow you to read and write named values in named registry keys. GetValue takes three arguments:
•A string containing the fully qualified name of the key you want to read. The key name must start with one of the following root key names:
•HKEY_CLASSES_ROOT
•HKEY_CURRENT_CONFIG
•HKEY_CURRENT_USER
•HKEY_DYN_DATA
•HKEY_LOCAL_MACHINE
•HKEY_PERFORMANCE_DATA
•HKEY_USERS
•A string containing the name of the value in the key you want to read.
•An object containing the default value to return if the named value is not present in the key.
GetValue returns an object containing either the data read from the registry or the default value specified as the third argument if the named value is not found. If the specified key does not exist, GetValue returns null.
SetValue offers two overloads. The most functional expects the following arguments:
•A string containing the fully qualified name of the key you want to write. The key must start with one of the root key names specified previously.
•A string containing the name of the value in the key you want to write.
•An object containing the value to write.
•An element of the Microsoft.Win32.RegistyValueKind enumeration that specifies the registry data type that should be used to hold the data.
If the registry key specified in the SetValue call does not exist, it is automatically created.
The Code
The following example demonstrates how to use GetValue and SetValue to read from and write to the registry. Every time the example is run, it reads usage information from the registry and displays it to the screen. The example also updates the stored usage information, which you can see the next time you run the example.

C H A P T E R 1 4 ■ W I N D O W S I N T E G R AT I O N |
507 |
using System;
using Microsoft.Win32;
namespace Apress.VisualCSharpRecipes.Chapter14
{
class Recipe14_04
{
public static void Main(String[] args)
{
//Variables to hold usage information read from registry. string lastUser;
string lastRun; int runCount;
//Read the name of the last user to run the application from the
//registry. This is stored as the default value of the key and is
//accessed by not specifying a value name. Cast the returned Object
//to a string.
lastUser = (string)Registry.GetValue( @"HKEY_CURRENT_USER\Software\Apress\Visual C# 2005 Recipes", "", "Nobody");
//If lastUser is null, it means that the specified registry key
//does not exist.
if (lastUser == null)
{
// Set initial values for the usage information. lastUser = "Nobody";
lastRun = "Never"; runCount = 0;
}
else
{
//Read the last run date and specify a default value of
//"Never". Cast the returned Object to string.
lastRun = (string)Registry.GetValue( @"HKEY_CURRENT_USER\Software\Apress\Visual C# 2005 Recipes", "LastRun", "Never");
//Read the run count value and specify a default value of
//0 (zero). Cast the Object to Int32, and assign to an int. runCount = (Int32)Registry.GetValue(
@"HKEY_CURRENT_USER\Software\Apress\Visual C# 2005 Recipes", "RunCount", 0);
}
//Display the usage information. Console.WriteLine("Last user name: " + lastUser); Console.WriteLine("Last run date/time: " + lastRun); Console.WriteLine("Previous executions: " + runCount);
//Update the usage information. It doesn't matter if the registry
//key exists or not, SetValue will automatically create it.