RaspberryIO/Unosquare.Swan.Lite/Runtime.cs

342 lines
11 KiB
C#
Raw Permalink Normal View History

2019-12-04 17:10:06 +01:00
using Unosquare.Swan.Components;
using System;
using System.IO;
using System.Threading;
using Unosquare.Swan.Reflection;
#if !NETSTANDARD1_3
using System.Reflection;
#endif
namespace Unosquare.Swan {
/// <summary>
/// Provides utility methods to retrieve information about the current application.
/// </summary>
#if !NETSTANDARD1_3
public class Runtime : MarshalByRefObject
2019-02-17 14:08:57 +01:00
#else
public static class Runtime
#endif
2019-12-04 17:10:06 +01:00
{
private static readonly Lazy<PropertyTypeCache> _propertyTypeCache = new Lazy<PropertyTypeCache>(() => new PropertyTypeCache());
private static readonly Lazy<AttributeCache> _attributeCache = new Lazy<AttributeCache>(() => new AttributeCache());
private static readonly Lazy<ObjectValidator> _objectValidator = new Lazy<ObjectValidator>(() => new ObjectValidator());
private static readonly Lazy<FieldTypeCache> _fieldTypeCache = new Lazy<FieldTypeCache>(() => new FieldTypeCache());
private static readonly Lazy<MethodInfoCache> _methodInfoCache = new Lazy<MethodInfoCache>(() => new MethodInfoCache());
2019-02-17 14:08:57 +01:00
#if NET452
2019-12-04 17:10:06 +01:00
private static readonly Lazy<Assembly> EntryAssemblyLazy = new Lazy<Assembly>(() => Assembly.GetEntryAssembly() ?? Assembly.GetExecutingAssembly());
2019-02-17 14:08:57 +01:00
#endif
2019-12-04 17:10:06 +01:00
2019-02-17 14:08:57 +01:00
#if NETSTANDARD2_0
private static readonly Lazy<Assembly> EntryAssemblyLazy = new Lazy<Assembly>(Assembly.GetEntryAssembly);
#endif
2019-12-04 17:10:06 +01:00
2019-02-17 14:08:57 +01:00
#if NET452
2019-12-04 17:10:06 +01:00
private static readonly Lazy<System.Diagnostics.Process> ProcessLazy = new Lazy<System.Diagnostics.Process>(System.Diagnostics.Process.GetCurrentProcess);
2019-02-17 14:08:57 +01:00
#endif
2019-12-04 17:10:06 +01:00
#if !NETSTANDARD1_3
private static readonly Lazy<String> CompanyNameLazy = new Lazy<String>(() => {
AssemblyCompanyAttribute attribute =
EntryAssembly.GetCustomAttribute(typeof(AssemblyCompanyAttribute)) as AssemblyCompanyAttribute;
return attribute?.Company ?? String.Empty;
});
private static readonly Lazy<String> ProductNameLazy = new Lazy<String>(() => {
AssemblyProductAttribute attribute =
EntryAssembly.GetCustomAttribute(typeof(AssemblyProductAttribute)) as AssemblyProductAttribute;
return attribute?.Product ?? String.Empty;
});
private static readonly Lazy<String> ProductTrademarkLazy = new Lazy<String>(() => {
AssemblyTrademarkAttribute attribute =
EntryAssembly.GetCustomAttribute(typeof(AssemblyTrademarkAttribute)) as AssemblyTrademarkAttribute;
return attribute?.Trademark ?? String.Empty;
});
2019-02-17 14:08:57 +01:00
#endif
2019-12-04 17:10:06 +01:00
private static readonly Lazy<ArgumentParser> _argumentParser =
new Lazy<ArgumentParser>(() => new ArgumentParser());
private static readonly Lazy<ObjectMapper> _objectMapper = new Lazy<ObjectMapper>(() => new ObjectMapper());
#if !NETSTANDARD1_3
private static readonly String ApplicationMutexName = "Global\\{{" + EntryAssembly.FullName + "}}";
2019-02-17 14:08:57 +01:00
#else
private const string ApplicationMutexName = "Global\\{{SWANINSTANCE}}";
#endif
2019-12-04 17:10:06 +01:00
private static readonly Object SyncLock = new Object();
private static OperatingSystem? _oS;
#region Properties
/// <summary>
/// Gets the current Operating System.
/// </summary>
/// <value>
/// The os.
/// </value>
public static OperatingSystem OS {
get {
if(_oS.HasValue == false) {
String windowsDirectory = Environment.GetEnvironmentVariable("windir");
_oS = String.IsNullOrEmpty(windowsDirectory) == false
&& windowsDirectory.Contains(@"\")
&& Directory.Exists(windowsDirectory)
? (OperatingSystem?)OperatingSystem.Windows
: (OperatingSystem?)(File.Exists(@"/proc/sys/kernel/ostype") ? OperatingSystem.Unix : OperatingSystem.Osx);
}
return _oS ?? OperatingSystem.Unknown;
}
}
2019-02-17 14:08:57 +01:00
#if NET452
2019-12-04 17:10:06 +01:00
/// <summary>
/// Gets the process associated with the current application.
/// </summary>
/// <value>
/// The process.
/// </value>
public static System.Diagnostics.Process Process => ProcessLazy.Value;
2019-02-17 14:08:57 +01:00
#endif
2019-12-04 17:10:06 +01:00
/// <summary>
/// Checks if this application (including version number) is the only instance currently running.
/// </summary>
/// <value>
/// <c>true</c> if this instance is the only instance; otherwise, <c>false</c>.
/// </value>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Codequalität", "IDE0067:Objekte verwerfen, bevor Bereich verloren geht", Justification = "<Ausstehend>")]
public static Boolean IsTheOnlyInstance {
get {
lock(SyncLock) {
try {
// Try to open existing mutex.
_ = Mutex.OpenExisting(ApplicationMutexName);
} catch {
try {
// If exception occurred, there is no such mutex.
Mutex appMutex = new Mutex(true, ApplicationMutexName);
$"Application Mutex created {appMutex} named '{ApplicationMutexName}'".Debug(
typeof(Runtime));
// Only one instance.
return true;
} catch {
// Sometimes the user can't create the Global Mutex
}
}
// More than one instance.
return false;
}
}
}
/// <summary>
/// Gets a value indicating whether this application instance is using the MONO runtime.
/// </summary>
/// <value>
/// <c>true</c> if this instance is using MONO runtime; otherwise, <c>false</c>.
/// </value>
public static Boolean IsUsingMonoRuntime => Type.GetType("Mono.Runtime") != null;
/// <summary>
/// Gets the property type cache.
/// </summary>
/// <value>
/// The property type cache.
/// </value>
public static PropertyTypeCache PropertyTypeCache => _propertyTypeCache.Value;
/// <summary>
/// Gets the attribute cache.
/// </summary>
/// <value>
/// The attribute cache.
/// </value>
public static AttributeCache AttributeCache => _attributeCache.Value;
/// <summary>
/// Gets the object validator.
/// </summary>
/// <value>
/// The object validator.
/// </value>
public static ObjectValidator ObjectValidator => _objectValidator.Value;
/// <summary>
/// Gets the field type cache.
/// </summary>
/// <value>
/// The field type cache.
/// </value>
public static FieldTypeCache FieldTypeCache => _fieldTypeCache.Value;
/// <summary>
/// Gets the method information cache.
/// </summary>
/// <value>
/// The method information cache.
/// </value>
public static MethodInfoCache MethodInfoCache => _methodInfoCache.Value;
#if !NETSTANDARD1_3
/// <summary>
/// Gets the assembly that started the application.
/// </summary>
/// <value>
/// The entry assembly.
/// </value>
public static Assembly EntryAssembly => EntryAssemblyLazy.Value;
/// <summary>
/// Gets the name of the entry assembly.
/// </summary>
/// <value>
/// The name of the entry assembly.
/// </value>
public static AssemblyName EntryAssemblyName => EntryAssemblyLazy.Value.GetName();
/// <summary>
/// Gets the entry assembly version.
/// </summary>
public static Version EntryAssemblyVersion => EntryAssemblyName.Version;
/// <summary>
/// Gets the full path to the folder containing the assembly that started the application.
/// </summary>
/// <value>
/// The entry assembly directory.
/// </value>
public static String EntryAssemblyDirectory {
get {
UriBuilder uri = new UriBuilder(EntryAssembly.CodeBase);
String path = Uri.UnescapeDataString(uri.Path);
return Path.GetDirectoryName(path);
}
}
/// <summary>
/// Gets the name of the company.
/// </summary>
/// <value>
/// The name of the company.
/// </value>
public static String CompanyName => CompanyNameLazy.Value;
/// <summary>
/// Gets the name of the product.
/// </summary>
/// <value>
/// The name of the product.
/// </value>
public static String ProductName => ProductNameLazy.Value;
/// <summary>
/// Gets the trademark.
/// </summary>
/// <value>
/// The product trademark.
/// </value>
public static String ProductTrademark => ProductTrademarkLazy.Value;
2019-02-17 14:08:57 +01:00
#endif
2019-12-04 17:10:06 +01:00
/// <summary>
/// Gets a local storage path with a version.
/// </summary>
/// <value>
/// The local storage path.
/// </value>
public static String LocalStoragePath {
get {
#if !NETSTANDARD1_3
String localAppDataPath =
2019-02-17 14:08:57 +01:00
#if NET452
2019-12-04 17:10:06 +01:00
Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),
EntryAssemblyName.Name);
2019-02-17 14:08:57 +01:00
#else
Path.GetDirectoryName(EntryAssembly.Location);
#endif
2019-12-04 17:10:06 +01:00
String returnPath = Path.Combine(localAppDataPath, EntryAssemblyVersion.ToString());
2019-02-17 14:08:57 +01:00
#else
var returnPath = Directory.GetCurrentDirectory(); // Use current path...
#endif
2019-12-04 17:10:06 +01:00
if(Directory.Exists(returnPath) == false) {
Directory.CreateDirectory(returnPath);
}
return returnPath;
}
}
/// <summary>
/// Gets the singleton instance created with basic defaults.
/// </summary>
/// <value>
/// The argument parser.
/// </value>
public static ArgumentParser ArgumentParser => _argumentParser.Value;
/// <summary>
/// Gets the object mapper instance created with basic defaults.
/// </summary>
/// <value>
/// The object mapper.
/// </value>
public static ObjectMapper ObjectMapper => _objectMapper.Value;
#endregion
#region Methods
#if !NETSTANDARD1_3
/// <summary>
/// Writes a standard banner to the standard output
/// containing the company name, product name, assembly version and trademark.
/// </summary>
/// <param name="color">The color.</param>
public static void WriteWelcomeBanner(ConsoleColor color = ConsoleColor.Gray) {
$"{CompanyName} {ProductName} [Version {EntryAssemblyVersion}]".WriteLine(color);
$"{ProductTrademark}".WriteLine(color);
}
/// <summary>
/// Gets all the loaded assemblies in the current application domain.
/// </summary>
/// <returns>An array of assemblies.</returns>
public static Assembly[] GetAssemblies() => AppDomain.CurrentDomain.GetAssemblies();
/// <summary>
/// Build a full path pointing to the current user's desktop with the given filename.
/// </summary>
/// <param name="filename">The filename.</param>
/// <returns>
/// The fully qualified location of path, such as "C:\MyFile.txt".
/// </returns>
/// <exception cref="ArgumentNullException">filename.</exception>
public static String GetDesktopFilePath(String filename) {
if(String.IsNullOrWhiteSpace(filename)) {
throw new ArgumentNullException(nameof(filename));
}
String pathWithFilename = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory),
filename);
return Path.GetFullPath(pathWithFilename);
}
2019-02-17 14:08:57 +01:00
#endif
2019-12-04 17:10:06 +01:00
#endregion
}
2019-02-17 14:08:57 +01:00
}