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
}