We take many environmental factors for granted when it comes to running our .NET applications. Information about the operating system may seem insignificant for folks deploying to rigorously maintained target environments. Still, for folks who publish desktop client software, the luxury of choosing the destination is not an option. This post will be using .NET to determine the operating system and architecture our .NET application is currently running within. We’ll also resolve the SDK version our app is utilizing. Finally, we’ll run our .NET code under three different operating systems to see the results: macOS, Windows, and Linux.
Why Does It Matter?
Most of the .NET Base Class Libraries (BCL) operate agnostically to the system they execute within. Some APIs delegate responsibility to the underlying operating system and utilize environment-specific implementations. Examples include interfaces for Linux, the FileSystemWatcher
class, and cryptography. We only need to search the dotnet/runtime
repository for “Linux” and see all the operating system mentions.
Understanding that behavior may be different depending on the target environment can save hours of debugging and frustration. The variance in behavior may also make us consider whether we want to try deploying to different target operating systems. We may not realize that high-level frameworks like ASP.NET Core depend on these low-level behaviors, so we can’t be entirely agnostic.
Using System.Runtime
.NET has a particular namespace that contains many helper classes for folks interested in revealing information about an app’s current environment; that namespace is System.Runtime.InteropServices
. Under the System.Runtime.InteropServices
namespace, we see two especially helpful classes: RuntimeInformation
and RuntimeEnvironment
.
Starting with RuntimeInformation
, we can see information about our current operating system and machine. We have the following static properties.
We also have access to a method of IsOSPlatform
, which takes an enum parameter of type OSPlatform
.
Our next class, RunTimeEnvironment
, where we have access to the following methods:
We also have a string
property of SystemConfigurationFile
. The support for this property is unavailable by most newer implementations of .NET and is likely still here for legacy support.
Let’s write an example using top-level statements that will give us an idea of our runtime environment.
Let’s run these in three different environments and see what we get!
Runtime Environments
Let’s start with macOS, my native development environment.
As we can see, the output is reflective of the host environment.
Let’s move onto Windows.
Running the same code on Windows yields different Windows-specific results.
With the results in the console being:
Finally, let’s run the same code under Linux.
Conclusion
If we’re writing code that needs to ship to multiple environments, the System.Runtime.InteropServices
is invaluable. An implementation may differ for each OS, and using these helper runtime features can help us branch and handle strange edge cases. I hope you found this post helpful. Please leave a comment below if you’ve had to use either RuntimeInformation
or RunTimeEnvironment
in your codebase.