C# Environment

Environment type

The Environment type returns information about the operating system context. It does not refer to the natural environment around us. Instead it describes the OS. It offers commonly-needed properties such as NewLine.

Tip:Environment methods and properties return information about the operating system and execution environment.

NewLine

On the Windows operating system, the newline is "\r\n". This is two characters. The Environment.NewLine property returns this string literal. It makes programs clearer in their intent.

Environment.NewLine

Exit

Program icon

Environment.Exit does not run finally statements. It provides a way to kill a process in its physical sense on the operating system. Clean-up of your program's resources does not occur. Finally statements are ignored.

Finally

Note:This method is located in the System namespace. It is a static method that receives an int—this is used as the exit code.

Using System

And:It asserts physical control on the process, disobeying the remaining logic in the high-level C# code.

Static Method
C# program that calls Environment.Exit with finally

using System;

class Program
{
    static void Main()
    {
	try
	{
	    //
	    // Calls the Environment.Exit method and returns a zero status code.
	    // ... The finally statement is never reached.
	    //
	    Environment.Exit(0);
	}
	finally
	{
	    Console.WriteLine("Finally statement");
	}
    }
}
Main method

This program describes the Main entry point, which uses the try-finally control structure. This block indicates a protected region of the code, where no matter what happens, the finally block is executed afterwards.

However:The finally block is not executed if the physical process is terminated directly.

So:Environment.Exit terminates the process and the statement in the finally block is never executed, as we see by running the program.

Warning: exclamation mark

In some console applications, the control structure is such that it is hard to signal to the Main entry point to immediately exit. In this case, using Environment.Exit is acceptable.

Threading. Because Environment.Exit acts upon the process of your program, all threads executing inside the process will be terminated with no warning if you call it. Other processes will not be terminated.

Threads

ExpandEnvironmentVariables

In the Windows operating system environment variables are used. They insert strings specific to the operating system's current setup. With the Environment ExpandEnvironmentVariables method, we expand these encoded variables.

Note:This program loops over a string array of environment variable string literals (they begin and also end with percent characters).

Next:We call Environment.ExpandEnvironmentVariables on each string literal and write the substituted result.

String Literal
C# program that expands environment variables

using System;

class Program
{
    static void Main()
    {
	string[] variables =
	{
	    "%WINDIR%",
	    "%HOMEDRIVE%",
	    "%USERNAME%",
	    "%COMPUTERNAME%"
	};
	foreach (string v in variables)
	{
	    string result = Environment.ExpandEnvironmentVariables(v);
	    Console.WriteLine(result);
	}
    }
}

Output

C:\Windows
C:
Sam2
SAM-PC2
Programming tip

Also, the ExpandEnvironmentVariables method will expand more than one variable in a string in a call. You can have other characters in the string and it will leave those untouched.

Warning:Some environment variables, such as RANDOM and DATE, are not supported according to my testing.

In programs that must handle encoded environment variables, it is probably much better to use ExpandEnvironmentVariables on the string input rather than replacing them yourself. This will yield standard behavior.

GetCommandLineArgs

Question

How does the Environment GetCommandLineArgs method work? You can receive command line arguments only in the Main entry point in the C# language. But the GetCommandLineArgs method can be used anywhere.

Main, Args

Next:This program shows how the args parameter is received in Main. It also shows how to use Environment.GetCommandLineArgs.

Note:The main difference is that the first element in the string array returned by GetCommandLineArgs is the program executable path.

String Array
C# program that uses Environment.GetCommandLineArgs

using System;

class Program
{
    static void Main(string[] args)
    {
	// Args does not contain the program path.
	Console.WriteLine(string.Join(",", args));

	// GetCommandLineArgs contains the program path as the first element.
	string[] array = Environment.GetCommandLineArgs();
	Console.WriteLine(string.Join(",", array));
    }
}

Output
    (Argument: dot net perls)
    (Second output line truncated.)

dot,net,perls
C:\Users\...\bin\Release\test.exe,dot,net,perls

Which should I use? It depends on your program. If you use the arguments immediately when the program begins, just use the args parameter. If your program uses the arguments later, you can use Environment.GetCommandLineArgs instead.

GetFolderPath

Path type

Environment.GetFolderPath returns a path string. It receives an enum of type Environment.SpecialFolder. It returns a string that depends on the user's current operating environment. The string includes the user's login name.

C# program that calls GetFolderPath

using System;

class Program
{
    static void Main()
    {
	string path = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
	Console.WriteLine(path);
    }
}

Output
    Varies depending on the operating environment.

C:\Users\Sam2\Desktop

Also, you may pass an Environment.SpecialFolderOption to GetFolderPath. This can be used to verify the existence of the location. If you specify Create, you can create the directory if it does not exist.

Performance optimization

Performance. In a benchmark program where the GetFolderPath call was run 100 thousand times. The result was that the method required 7179 nanoseconds per call, which is 7 microseconds.

Note:If you stored the result of GetFolderPath in a static string, you could load that in a couple nanoseconds.

Thus:It would be much faster—3000 times faster—to cache the result of GetFolderPath if it is used frequently.

GetLogicalDrives

What disk drives are present on the current computer? With the Environment.GetLogicalDrives method, you can determine where to search for files on local drives. It returns a string array.

Logical drives may not be separate physically, but to the Windows operating system, they are "logically" separate. A partition on a hard disk is a logical drive. A USB disk is also a logical as well as physical drive.

C# program that shows GetLogicalDrives

using System;

class Program
{
    static void Main()
    {
	string[] value = Environment.GetLogicalDrives();
	Console.WriteLine(string.Join(",", value));
    }
}

Output

C:\,D:\,H:\

How can we detect when a user inserts (mounts) a drive on the current computer? One way you could do this is simply call GetLogicalDrives on a Timer. Ask the computer what drives are mounted every several seconds.

Timer

Then:If this array changes, you know something was added or removed. This may not be the most efficient approach.

ProcessorCount

Property

What does the Environment ProcessorCount property do? Processors can have multiple cores. The ProcessorCount property in the .NET Framework returns the total number of cores on a computer, not processors.

Tip:Environment.ProcessorCount returns an int.
It indicates how many cores all your computer's processors have.

Framework: NET

This program shows that the dual-core, single processor computer I execute it on returns 2 for ProcessorCount.
Conceptually,
you can consider these logical,
but not physical,
processors. The computer has only one physical processor.

C# program that accesses ProcessorCount

using System;

class Program
{
    static void Main()
    {
	Console.WriteLine(Environment.ProcessorCount);
    }
}

Output

2

The ProcessorCount property in the .NET Framework returns the number of logical processors in the executing computer. This means each core is considered a discrete processor, rather than part of a single processor.

So:You can use this property for creating an array of Threads to fully use the computer's computational resources.

SpecialFolder

File

Microsoft Windows has special folders. Microsoft Word will save to Documents, and Windows Media Player will use the Music folder. We use the Environment.SpecialFolder enum in the .NET Framework to locate these special folders.

Locations:

Desktop
DesktopDirectory
MyDocuments
MyMusic
MyPictures
Programs
StartMenu
Startup

In Visual Studio, we can type in Environment.SpecialFolder, press period and get a list of values. For our example, we will use MyDocuments. This is an ideal place for business files. We combine SpecialFolder with GetFolderPath.

Fragment that uses Environment.SpecialFolder: C#

public partial class ExampleForm : Form
{
    // Initialize the controls on the form in the constructor here.
    public ExampleForm()
    {
	InitializeComponent();
	openFileDialog1.InitialDirectory =
	    Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
    }
}

The example initializes the open file dialog's location to My Documents, or in Vista just Documents. On Windows 7, it may initialize to an even different location. This means the user won't be shown some strange file system location.

OpenFileDialogString type

Also, this code is not restricted to usage with InitialDirectory. GetFolderPath simply converts the enum into a usable string by the system. You can assign it like we see in the following example.

Fragment that uses Environment.GetFolderPath: C#

private void TestMethod()
{
    //
    // Store the location of Pictures folder in a string.
    //
    Environment.SpecialFolder special = Environment.SpecialFolder.MyPictures;
    string folderLocation = Environment.GetFolderPath(special);
}

Summary

As a developer it is common to use the Environment type in all kinds of C# programs. It is a handy way to interact with the operating system environment. This eliminates the need to use interoperability calls to get this information.


C#: .NET