//******************************************************************************************************// Common.cs - Gbtc//// Copyright © 2012, Grid Protection Alliance. All Rights Reserved.//// Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See// the NOTICE file distributed with this work for additional information regarding copyright ownership.// The GPA licenses this file to you under the MIT License (MIT), the "License"; you may// not use this file except in compliance with the License. You may obtain a copy of the License at://// http://www.opensource.org/licenses/MIT//// Unless agreed to in writing, the subject software distributed under the License is distributed on an// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the// License for the specific language governing permissions and limitations.//// Code Modification History:// ----------------------------------------------------------------------------------------------------// 04/03/2006 - J. Ritchie Carroll// Generated original version of source code.// 12/13/2007 - Darrell Zuercher// Edited code comments.// 09/08/2008 - J. Ritchie Carroll// Converted to C#.// 02/13/2009 - Josh L. Patterson// Edited Code Comments.// 09/14/2009 - Stephen C. Wills// Added new header and license agreement.// 09/17/2009 - Pinal C. Patel// Modified GetApplicationType() to remove dependency on HttpContext.Current.// 09/28/2010 - Pinal C. Patel// Cached the current ApplicationType returned by GetApplicationType() for better performance.// 12/05/2010 - Pinal C. Patel// Added an overload for TypeConvertToString() that takes CultureInfo as a parameter.// 12/07/2010 - Pinal C. Patel// Updated TypeConvertToString() to return an empty string if the passed in value is null.// 03/09/2011 - Pinal C. Patel// Moved UpdateType enumeration from GSF.Services.ServiceProcess namespace for broader usage.// 04/07/2011 - J. Ritchie Carroll// Added ToNonNullNorEmptyString() and ToNonNullNorWhiteSpace() extensions.// 12/14/2012 - Starlynn Danyelle Gilliam// Modified Header.////****************************************************************************************************** using System;using System.Collections.Generic;using System.ComponentModel;using System.Diagnostics;using System.Globalization;using System.IO;using System.Linq;using System.Runtime.CompilerServices;using System.Web.Hosting;using GSF.Collections;using GSF.Console;using GSF.IO;using GSF.Reflection;using Microsoft.Win32; namespace GSF{ #region [ Enumerations ] /// <summary> /// Specifies the type of the application. /// </summary> public enum ApplicationType { /// <summary> /// Application is of unknown type. /// </summary> Unknown = 0, /// <summary> /// Application doesn't require a subsystem. /// </summary> Native = 1, /// <summary> /// Application runs in the Windows GUI subsystem. /// </summary> WindowsGui = 2, /// <summary> /// Application runs in the Windows character subsystem. /// </summary> WindowsCui = 3, /// <summary> /// Application runs in the OS/2 character subsystem. /// </summary> OS2Cui = 5, /// <summary> /// Application runs in the POSIX character subsystem. /// </summary> PosixCui = 7, /// <summary> /// Application is a native Win9x driver. /// </summary> NativeWindows = 8, /// <summary> /// Application runs in the Windows CE subsystem. /// </summary> WindowsCEGui = 9, /// <summary> /// The application is a web site or web application. /// </summary> Web = 100 } /// <summary> /// Indicates the type of update. /// </summary> public enum UpdateType { /// <summary> /// Update is informational. /// </summary> Information, /// <summary> /// Update is a warning. /// </summary> Warning, /// <summary> /// Update is an alarm. /// </summary> Alarm } #endregion // This is the location for handy miscellaneous functions that are difficult to categorize elsewhere. For the most // part these functions may have the most value in a Visual Basic application which supports importing functions // down to a class level, e.g.: Imports GSF.Common /// <summary> /// Defines common global functions. /// </summary> public static class Common { private static ApplicationType? s_applicationType; private static string s_osPlatformName; private static PlatformID s_osPlatformID = PlatformID.Win32S; /// <summary> /// Determines if the current system is a POSIX style environment. /// </summary> /// <remarks> /// <para> /// Since a .NET application compiled under Mono can run under both Windows and Unix style platforms, /// you can use this property to easily determine the current operating environment. /// </para> /// <para> /// This property will return <c>true</c> for both MacOSX and Unix environments. Use the Platform property /// of the <see cref="System.Environment.OSVersion"/> to determine more specific platform type, e.g., /// MacOSX or Unix. Note that all flavors of Linux will show up as <see cref="PlatformID.Unix"/>. /// </para> /// </remarks> public static readonly bool IsPosixEnvironment = (Path.DirectorySeparatorChar == '/'); // This is how Mono source often checks this /// <summary> /// Determines if the code base is currently running under Mono. /// </summary> /// <remarks> /// This property can be used to make a run-time determination if Windows or Mono based .NET is being used. However, it is /// highly recommended to use the MONO compiler directive wherever possible instead of determining this at run-time. /// </remarks> public static bool IsMono = ((object)Type.GetType("Mono.Runtime") != null); /// <summary>Returns one of two strongly-typed objects.</summary> /// <returns>One of two objects, depending on the evaluation of given expression.</returns> /// <param name="expression">The expression you want to evaluate.</param> /// <param name="truePart">Returned if expression evaluates to True.</param> /// <param name="falsePart">Returned if expression evaluates to False.</param> /// <typeparam name="T">Return type used for immediate expression</typeparam> /// <remarks> /// <para>This function acts as a strongly-typed immediate if (a.k.a. inline if).</para> /// <para> /// It is expected that this function will only be used in languages that do not support ?: conditional operations, e.g., Visual Basic.NET. /// In Visual Basic this function can be used as a strongly-typed IIf replacement by specifying "Imports GSF.Common". /// </para> /// </remarks> [MethodImpl(MethodImplOptions.AggressiveInlining)] public static T IIf<T>(bool expression, T truePart, T falsePart) { return (expression ? truePart : falsePart); } /// <summary>Creates a strongly-typed Array.</summary> /// <returns>New array of specified type.</returns> /// <param name="length">Desired length of new array.</param> /// <typeparam name="T">Return type for new array.</typeparam> /// <remarks> /// <para>It is expected that this function will only be used in Visual Basic.NET.</para> /// <para> /// The Array.CreateInstance provides better performance and more direct CLR access for array creation (not to /// mention less confusion on the matter of array lengths) in VB.NET, however the returned System.Array is not /// typed properly. This function properly casts the return array based on the type specification helping /// when Option Strict is enabled. /// </para> /// </remarks> /// <example> /// <code language="VB"> /// Dim buffer As Byte() = CreateArray(Of Byte)(12) /// Dim matrix As Integer()() = CreateArray(Of Integer())(10) /// </code> /// </example> [MethodImpl(MethodImplOptions.AggressiveInlining)] public static T[] CreateArray<T>(int length) { // The following provides better performance than "Return New T(length) {}". // ReSharper disable once UseArrayCreationExpression.1 return (T[])Array.CreateInstance(typeof(T), length); } /// <summary>Creates a strongly-typed Array with an initial value parameter.</summary> /// <returns>New array of specified type.</returns> /// <param name="length">Desired length of new array.</param> /// <param name="initialValue">Value used to initialize all array elements.</param> /// <typeparam name="T">Return type for new array.</typeparam> /// <remarks> /// It is expected that this function will only be used in Visual Basic.NET. /// </remarks> /// <example> /// <code language="VB"> /// Dim elements As Integer() = CreateArray(12, -1) /// Dim names As String() = CreateArray(100, "undefined") /// </code> /// </example> [MethodImpl(MethodImplOptions.AggressiveInlining)] public static T[] CreateArray<T>(int length, T initialValue) { T[] typedArray = CreateArray<T>(length); // Initializes all elements with the default value. for (int x = 0; x < typedArray.Length; x++) { typedArray[x] = initialValue; } return typedArray; } /// <summary> /// Gets the type of the currently executing application. /// </summary> /// <returns>One of the <see cref="ApplicationType"/> values.</returns> public static ApplicationType GetApplicationType() { if (s_applicationType.HasValue) return s_applicationType.Value; if (HostingEnvironment.IsHosted) { s_applicationType = ApplicationType.Web; } else { try { // References: // - http://support.microsoft.com/kb/65122 // - http://support.microsoft.com/kb/90493/en-us // - http://www.codeguru.com/cpp/w-p/system/misc/article.php/c2897/ // We will always have an entry assembly for windows application. FileStream exe = new FileStream(AssemblyInfo.EntryAssembly.Location, FileMode.Open, FileAccess.Read, FileShare.ReadWrite); byte[] dosHeader = new byte[64]; byte[] exeHeader = new byte[248]; byte[] subSystem = new byte[2]; exe.Read(dosHeader, 0, dosHeader.Length); exe.Seek(BitConverter.ToInt16(dosHeader, 60), SeekOrigin.Begin); exe.Read(exeHeader, 0, exeHeader.Length); exe.Close(); Buffer.BlockCopy(exeHeader, 92, subSystem, 0, 2); s_applicationType = ((ApplicationType)(LittleEndian.ToInt16(subSystem, 0))); } catch { // We are unable to determine the application type. s_applicationType = ApplicationType.Unknown; } } return s_applicationType.Value; } /// <summary> /// Gets the operating system <see cref="PlatformID"/> /// </summary> /// <returns>The operating system <see cref="PlatformID"/>.</returns> /// <remarks> /// This function will properly detect the platform ID, even if running on Mac. /// </remarks> public static PlatformID GetOSPlatformID() { if (s_osPlatformID != PlatformID.Win32S) return s_osPlatformID; s_osPlatformID = Environment.OSVersion.Platform; if (s_osPlatformID == PlatformID.Unix) { // Environment.OSVersion.Platform can report Unix when running on Mac OS X try { s_osPlatformID = Command.Execute("uname").StandardOutput.StartsWith("Darwin", StringComparison.OrdinalIgnoreCase) ? PlatformID.MacOSX : PlatformID.Unix; } catch { // Fall back on looking for Mac specific root folders: if (Directory.Exists("/Applications") && Directory.Exists("/System") && Directory.Exists("/Users") && Directory.Exists("/Volumes")) s_osPlatformID = PlatformID.MacOSX; } } return s_osPlatformID; } /// <summary> /// Gets the operating system product name. /// </summary> /// <returns>Operating system product name.</returns> public static string GetOSProductName() { if ((object)s_osPlatformName != null) return s_osPlatformName; switch (GetOSPlatformID()) { case PlatformID.Unix: case PlatformID.MacOSX: // Call sw_vers on Mac to get product name and version information, Linux could have this try { string output = Command.Execute("sw_vers").StandardOutput; Dictionary<string, string> kvps = output.ParseKeyValuePairs('\n', ':'); if (kvps.Count > 0) s_osPlatformName = kvps.Values.Select(val => val.Trim()).ToDelimitedString(" "); } catch { s_osPlatformName = null; } if (string.IsNullOrEmpty(s_osPlatformName)) { // Try some common ways to get product name on Linux, some might work on Mac try { foreach (string fileName in FilePath.GetFileList("/etc/*release*")) { using (StreamReader reader = new StreamReader(fileName)) { string line = reader.ReadLine(); while ((object)line != null) { if (line.StartsWith("PRETTY_NAME", StringComparison.OrdinalIgnoreCase) && !line.Contains('#')) { string[] parts = line.Split('='); if (parts.Length == 2) { s_osPlatformName = parts[1].Replace("\"", ""); break; } } line = reader.ReadLine(); } } if (!string.IsNullOrEmpty(s_osPlatformName)) break; } } catch { try { string output = Command.Execute("lsb_release", "-a").StandardOutput; Dictionary<string, string> kvps = output.ParseKeyValuePairs('\n', ':'); if (kvps.TryGetValue("Description", out s_osPlatformName) && !string.IsNullOrEmpty(s_osPlatformName)) s_osPlatformName = s_osPlatformName.Trim(); } catch { s_osPlatformName = null; } } } break; default: // Get Windows product name try { s_osPlatformName = Registry.GetValue("HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", "ProductName", null).ToString(); } catch { s_osPlatformName = null; } break; } if (string.IsNullOrWhiteSpace(s_osPlatformName)) s_osPlatformName = GetOSPlatformID().ToString(); if (IsMono) s_osPlatformName += " using Mono"; return s_osPlatformName; } /// <summary> /// Gets the memory usage by the current process. /// </summary> /// <returns>Memory usage by the current process.</returns> public static long GetProcessMemory() { long processMemory = Environment.WorkingSet; if (processMemory == 0 && IsPosixEnvironment) { try { double percentOfTotal; long totalMemory; // Get total system memory using (PerformanceCounter counter = new PerformanceCounter("Mono Memory", "Total Physical Memory")) totalMemory = counter.RawValue; // Get percent of total memory used by current process string output = Command.Execute("ps", string.Format("-p {0} -o %mem", Process.GetCurrentProcess().Id)).StandardOutput; string[] lines = output.Split('\n'); if (lines.Length > 1 && double.TryParse(lines[1].Trim(), out percentOfTotal)) processMemory = (long)Math.Round(percentOfTotal / 100.0D * totalMemory); } catch { processMemory = -1; } } return processMemory; } // The following "ToNonNullString" methods extend all class based objects. Note that these extension methods can be // called even if the base object is null, hence the value of these methods. Our philosophy for this project has been // "not" to apply extensions to all objects (this to avoid general namespace pollution) and make sure extensions are // grouped together in their own source file (e.g., StringExtensions.cs); however these items do apply to all items // and are essentially type-less hence their location in the "Common" class. These extension methods are at least // limited to classes and won't show up on native types and custom structures. /// <summary> /// Converts value to string; null objects (or DBNull objects) will return an empty string (""). /// </summary> /// <typeparam name="T"><see cref="Type"/> of <see cref="Object"/> to convert to string.</typeparam> /// <param name="value">Value to convert to string.</param> /// <returns><paramref name="value"/> as a string; if <paramref name="value"/> is null, empty string ("") will be returned. </returns> [MethodImpl(MethodImplOptions.AggressiveInlining)] public static string ToNonNullString<T>(this T value) where T : class { return ((object)value == null || value is DBNull ? "" : value.ToString()); } /// <summary> /// Converts value to string; null objects (or DBNull objects) will return specified <paramref name="nonNullValue"/>. /// </summary> /// <typeparam name="T"><see cref="Type"/> of <see cref="Object"/> to convert to string.</typeparam> /// <param name="value">Value to convert to string.</param> /// <param name="nonNullValue"><see cref="String"/> to return if <paramref name="value"/> is null.</param> /// <returns><paramref name="value"/> as a string; if <paramref name="value"/> is null, <paramref name="nonNullValue"/> will be returned.</returns> /// <exception cref="ArgumentNullException"><paramref name="nonNullValue"/> cannot be null.</exception> public static string ToNonNullString<T>(this T value, string nonNullValue) where T : class { if ((object)nonNullValue == null) throw new ArgumentNullException("nonNullValue"); return ((object)value == null || value is DBNull ? nonNullValue : value.ToString()); } // We handle strings as a special version of the ToNullNullString extension to handle documentation a little differently /// <summary> /// Makes sure returned string value is not null; if this string is null, empty string ("") will be returned. /// </summary> /// <param name="value"><see cref="String"/> to verify is not null.</param> /// <returns><see cref="String"/> value; if <paramref name="value"/> is null, empty string ("") will be returned.</returns> [MethodImpl(MethodImplOptions.AggressiveInlining)] public static string ToNonNullString(this string value) { return ((object)value == null ? "" : value); } /// <summary> /// Converts value to string; null objects, DBNull objects or empty strings will return specified <paramref name="nonNullNorEmptyValue"/>.Lines 1–500 of 862. Load more
//****************************************************************************************************** // Common.cs - Gbtc // // Copyright © 2012, Grid Protection Alliance. All Rights Reserved. // // Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See // the NOTICE file distributed with this work for additional information regarding copyright ownership. // The GPA licenses this file to you under the MIT License (MIT), the "License"; you may // not use this file except in compliance with the License. You may obtain a copy of the License at: // // http://www.opensource.org/licenses/MIT // // Unless agreed to in writing, the subject software distributed under the License is distributed on an // "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the // License for the specific language governing permissions and limitations. // // Code Modification History: // ---------------------------------------------------------------------------------------------------- // 04/03/2006 - J. Ritchie Carroll // Generated original version of source code. // 12/13/2007 - Darrell Zuercher // Edited code comments. // 09/08/2008 - J. Ritchie Carroll // Converted to C#. // 02/13/2009 - Josh L. Patterson // Edited Code Comments. // 09/14/2009 - Stephen C. Wills // Added new header and license agreement. // 09/17/2009 - Pinal C. Patel // Modified GetApplicationType() to remove dependency on HttpContext.Current. // 09/28/2010 - Pinal C. Patel // Cached the current ApplicationType returned by GetApplicationType() for better performance. // 12/05/2010 - Pinal C. Patel // Added an overload for TypeConvertToString() that takes CultureInfo as a parameter. // 12/07/2010 - Pinal C. Patel // Updated TypeConvertToString() to return an empty string if the passed in value is null. // 03/09/2011 - Pinal C. Patel // Moved UpdateType enumeration from GSF.Services.ServiceProcess namespace for broader usage. // 04/07/2011 - J. Ritchie Carroll // Added ToNonNullNorEmptyString() and ToNonNullNorWhiteSpace() extensions. // 12/14/2012 - Starlynn Danyelle Gilliam // Modified Header. // //****************************************************************************************************** using System; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; using System.Runtime.CompilerServices; using System.Web.Hosting; using GSF.Collections; using GSF.Console; using GSF.IO; using GSF.Reflection; using Microsoft.Win32; namespace GSF { #region [ Enumerations ] /// <summary> /// Specifies the type of the application. /// </summary> public enum ApplicationType { /// <summary> /// Application is of unknown type. /// </summary> Unknown = 0, /// <summary> /// Application doesn't require a subsystem. /// </summary> Native = 1, /// <summary> /// Application runs in the Windows GUI subsystem. /// </summary> WindowsGui = 2, /// <summary> /// Application runs in the Windows character subsystem. /// </summary> WindowsCui = 3, /// <summary> /// Application runs in the OS/2 character subsystem. /// </summary> OS2Cui = 5, /// <summary> /// Application runs in the POSIX character subsystem. /// </summary> PosixCui = 7, /// <summary> /// Application is a native Win9x driver. /// </summary> NativeWindows = 8, /// <summary> /// Application runs in the Windows CE subsystem. /// </summary> WindowsCEGui = 9, /// <summary> /// The application is a web site or web application. /// </summary> Web = 100 } /// <summary> /// Indicates the type of update. /// </summary> public enum UpdateType { /// <summary> /// Update is informational. /// </summary> Information, /// <summary> /// Update is a warning. /// </summary> Warning, /// <summary> /// Update is an alarm. /// </summary> Alarm } #endregion // This is the location for handy miscellaneous functions that are difficult to categorize elsewhere. For the most // part these functions may have the most value in a Visual Basic application which supports importing functions // down to a class level, e.g.: Imports GSF.Common /// <summary> /// Defines common global functions. /// </summary> public static class Common { private static ApplicationType? s_applicationType; private static string s_osPlatformName; private static PlatformID s_osPlatformID = PlatformID.Win32S; /// <summary> /// Determines if the current system is a POSIX style environment. /// </summary> /// <remarks> /// <para> /// Since a .NET application compiled under Mono can run under both Windows and Unix style platforms, /// you can use this property to easily determine the current operating environment. /// </para> /// <para> /// This property will return <c>true</c> for both MacOSX and Unix environments. Use the Platform property /// of the <see cref="System.Environment.OSVersion"/> to determine more specific platform type, e.g., /// MacOSX or Unix. Note that all flavors of Linux will show up as <see cref="PlatformID.Unix"/>. /// </para> /// </remarks> public static readonly bool IsPosixEnvironment = (Path.DirectorySeparatorChar == '/'); // This is how Mono source often checks this /// <summary> /// Determines if the code base is currently running under Mono. /// </summary> /// <remarks> /// This property can be used to make a run-time determination if Windows or Mono based .NET is being used. However, it is /// highly recommended to use the MONO compiler directive wherever possible instead of determining this at run-time. /// </remarks> public static bool IsMono = ((object)Type.GetType("Mono.Runtime") != null); /// <summary>Returns one of two strongly-typed objects.</summary> /// <returns>One of two objects, depending on the evaluation of given expression.</returns> /// <param name="expression">The expression you want to evaluate.</param> /// <param name="truePart">Returned if expression evaluates to True.</param> /// <param name="falsePart">Returned if expression evaluates to False.</param> /// <typeparam name="T">Return type used for immediate expression</typeparam> /// <remarks> /// <para>This function acts as a strongly-typed immediate if (a.k.a. inline if).</para> /// <para> /// It is expected that this function will only be used in languages that do not support ?: conditional operations, e.g., Visual Basic.NET. /// In Visual Basic this function can be used as a strongly-typed IIf replacement by specifying "Imports GSF.Common". /// </para> /// </remarks> [MethodImpl(MethodImplOptions.AggressiveInlining)] public static T IIf<T>(bool expression, T truePart, T falsePart) { return (expression ? truePart : falsePart); } /// <summary>Creates a strongly-typed Array.</summary> /// <returns>New array of specified type.</returns> /// <param name="length">Desired length of new array.</param> /// <typeparam name="T">Return type for new array.</typeparam> /// <remarks> /// <para>It is expected that this function will only be used in Visual Basic.NET.</para> /// <para> /// The Array.CreateInstance provides better performance and more direct CLR access for array creation (not to /// mention less confusion on the matter of array lengths) in VB.NET, however the returned System.Array is not /// typed properly. This function properly casts the return array based on the type specification helping /// when Option Strict is enabled. /// </para> /// </remarks> /// <example> /// <code language="VB"> /// Dim buffer As Byte() = CreateArray(Of Byte)(12) /// Dim matrix As Integer()() = CreateArray(Of Integer())(10) /// </code> /// </example> [MethodImpl(MethodImplOptions.AggressiveInlining)] public static T[] CreateArray<T>(int length) { // The following provides better performance than "Return New T(length) {}". // ReSharper disable once UseArrayCreationExpression.1 return (T[])Array.CreateInstance(typeof(T), length); } /// <summary>Creates a strongly-typed Array with an initial value parameter.</summary> /// <returns>New array of specified type.</returns> /// <param name="length">Desired length of new array.</param> /// <param name="initialValue">Value used to initialize all array elements.</param> /// <typeparam name="T">Return type for new array.</typeparam> /// <remarks> /// It is expected that this function will only be used in Visual Basic.NET. /// </remarks> /// <example> /// <code language="VB"> /// Dim elements As Integer() = CreateArray(12, -1) /// Dim names As String() = CreateArray(100, "undefined") /// </code> /// </example> [MethodImpl(MethodImplOptions.AggressiveInlining)] public static T[] CreateArray<T>(int length, T initialValue) { T[] typedArray = CreateArray<T>(length); // Initializes all elements with the default value. for (int x = 0; x < typedArray.Length; x++) { typedArray[x] = initialValue; } return typedArray; } /// <summary> /// Gets the type of the currently executing application. /// </summary> /// <returns>One of the <see cref="ApplicationType"/> values.</returns> public static ApplicationType GetApplicationType() { if (s_applicationType.HasValue) return s_applicationType.Value; if (HostingEnvironment.IsHosted) { s_applicationType = ApplicationType.Web; } else { try { // References: // - http://support.microsoft.com/kb/65122 // - http://support.microsoft.com/kb/90493/en-us // - http://www.codeguru.com/cpp/w-p/system/misc/article.php/c2897/ // We will always have an entry assembly for windows application. FileStream exe = new FileStream(AssemblyInfo.EntryAssembly.Location, FileMode.Open, FileAccess.Read, FileShare.ReadWrite); byte[] dosHeader = new byte[64]; byte[] exeHeader = new byte[248]; byte[] subSystem = new byte[2]; exe.Read(dosHeader, 0, dosHeader.Length); exe.Seek(BitConverter.ToInt16(dosHeader, 60), SeekOrigin.Begin); exe.Read(exeHeader, 0, exeHeader.Length); exe.Close(); Buffer.BlockCopy(exeHeader, 92, subSystem, 0, 2); s_applicationType = ((ApplicationType)(LittleEndian.ToInt16(subSystem, 0))); } catch { // We are unable to determine the application type. s_applicationType = ApplicationType.Unknown; } } return s_applicationType.Value; } /// <summary> /// Gets the operating system <see cref="PlatformID"/> /// </summary> /// <returns>The operating system <see cref="PlatformID"/>.</returns> /// <remarks> /// This function will properly detect the platform ID, even if running on Mac. /// </remarks> public static PlatformID GetOSPlatformID() { if (s_osPlatformID != PlatformID.Win32S) return s_osPlatformID; s_osPlatformID = Environment.OSVersion.Platform; if (s_osPlatformID == PlatformID.Unix) { // Environment.OSVersion.Platform can report Unix when running on Mac OS X try { s_osPlatformID = Command.Execute("uname").StandardOutput.StartsWith("Darwin", StringComparison.OrdinalIgnoreCase) ? PlatformID.MacOSX : PlatformID.Unix; } catch { // Fall back on looking for Mac specific root folders: if (Directory.Exists("/Applications") && Directory.Exists("/System") && Directory.Exists("/Users") && Directory.Exists("/Volumes")) s_osPlatformID = PlatformID.MacOSX; } } return s_osPlatformID; } /// <summary> /// Gets the operating system product name. /// </summary> /// <returns>Operating system product name.</returns> public static string GetOSProductName() { if ((object)s_osPlatformName != null) return s_osPlatformName; switch (GetOSPlatformID()) { case PlatformID.Unix: case PlatformID.MacOSX: // Call sw_vers on Mac to get product name and version information, Linux could have this try { string output = Command.Execute("sw_vers").StandardOutput; Dictionary<string, string> kvps = output.ParseKeyValuePairs('\n', ':'); if (kvps.Count > 0) s_osPlatformName = kvps.Values.Select(val => val.Trim()).ToDelimitedString(" "); } catch { s_osPlatformName = null; } if (string.IsNullOrEmpty(s_osPlatformName)) { // Try some common ways to get product name on Linux, some might work on Mac try { foreach (string fileName in FilePath.GetFileList("/etc/*release*")) { using (StreamReader reader = new StreamReader(fileName)) { string line = reader.ReadLine(); while ((object)line != null) { if (line.StartsWith("PRETTY_NAME", StringComparison.OrdinalIgnoreCase) && !line.Contains('#')) { string[] parts = line.Split('='); if (parts.Length == 2) { s_osPlatformName = parts[1].Replace("\"", ""); break; } } line = reader.ReadLine(); } } if (!string.IsNullOrEmpty(s_osPlatformName)) break; } } catch { try { string output = Command.Execute("lsb_release", "-a").StandardOutput; Dictionary<string, string> kvps = output.ParseKeyValuePairs('\n', ':'); if (kvps.TryGetValue("Description", out s_osPlatformName) && !string.IsNullOrEmpty(s_osPlatformName)) s_osPlatformName = s_osPlatformName.Trim(); } catch { s_osPlatformName = null; } } } break; default: // Get Windows product name try { s_osPlatformName = Registry.GetValue("HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", "ProductName", null).ToString(); } catch { s_osPlatformName = null; } break; } if (string.IsNullOrWhiteSpace(s_osPlatformName)) s_osPlatformName = GetOSPlatformID().ToString(); if (IsMono) s_osPlatformName += " using Mono"; return s_osPlatformName; } /// <summary> /// Gets the memory usage by the current process. /// </summary> /// <returns>Memory usage by the current process.</returns> public static long GetProcessMemory() { long processMemory = Environment.WorkingSet; if (processMemory == 0 && IsPosixEnvironment) { try { double percentOfTotal; long totalMemory; // Get total system memory using (PerformanceCounter counter = new PerformanceCounter("Mono Memory", "Total Physical Memory")) totalMemory = counter.RawValue; // Get percent of total memory used by current process string output = Command.Execute("ps", string.Format("-p {0} -o %mem", Process.GetCurrentProcess().Id)).StandardOutput; string[] lines = output.Split('\n'); if (lines.Length > 1 && double.TryParse(lines[1].Trim(), out percentOfTotal)) processMemory = (long)Math.Round(percentOfTotal / 100.0D * totalMemory); } catch { processMemory = -1; } } return processMemory; } // The following "ToNonNullString" methods extend all class based objects. Note that these extension methods can be // called even if the base object is null, hence the value of these methods. Our philosophy for this project has been // "not" to apply extensions to all objects (this to avoid general namespace pollution) and make sure extensions are // grouped together in their own source file (e.g., StringExtensions.cs); however these items do apply to all items // and are essentially type-less hence their location in the "Common" class. These extension methods are at least // limited to classes and won't show up on native types and custom structures. /// <summary> /// Converts value to string; null objects (or DBNull objects) will return an empty string (""). /// </summary> /// <typeparam name="T"><see cref="Type"/> of <see cref="Object"/> to convert to string.</typeparam> /// <param name="value">Value to convert to string.</param> /// <returns><paramref name="value"/> as a string; if <paramref name="value"/> is null, empty string ("") will be returned. </returns> [MethodImpl(MethodImplOptions.AggressiveInlining)] public static string ToNonNullString<T>(this T value) where T : class { return ((object)value == null || value is DBNull ? "" : value.ToString()); } /// <summary> /// Converts value to string; null objects (or DBNull objects) will return specified <paramref name="nonNullValue"/>. /// </summary> /// <typeparam name="T"><see cref="Type"/> of <see cref="Object"/> to convert to string.</typeparam> /// <param name="value">Value to convert to string.</param> /// <param name="nonNullValue"><see cref="String"/> to return if <paramref name="value"/> is null.</param> /// <returns><paramref name="value"/> as a string; if <paramref name="value"/> is null, <paramref name="nonNullValue"/> will be returned.</returns> /// <exception cref="ArgumentNullException"><paramref name="nonNullValue"/> cannot be null.</exception> public static string ToNonNullString<T>(this T value, string nonNullValue) where T : class { if ((object)nonNullValue == null) throw new ArgumentNullException("nonNullValue"); return ((object)value == null || value is DBNull ? nonNullValue : value.ToString()); } // We handle strings as a special version of the ToNullNullString extension to handle documentation a little differently /// <summary> /// Makes sure returned string value is not null; if this string is null, empty string ("") will be returned. /// </summary> /// <param name="value"><see cref="String"/> to verify is not null.</param> /// <returns><see cref="String"/> value; if <paramref name="value"/> is null, empty string ("") will be returned.</returns> [MethodImpl(MethodImplOptions.AggressiveInlining)] public static string ToNonNullString(this string value) { return ((object)value == null ? "" : value); } /// <summary> /// Converts value to string; null objects, DBNull objects or empty strings will return specified <paramref name="nonNullNorEmptyValue"/>.