using Swan.Logging; using System; using System.IO; using System.Reflection; using System.Threading; namespace Swan { /// /// Provides utility methods to retrieve information about the current application. /// public static class SwanRuntime { private static readonly Lazy EntryAssemblyLazy = new Lazy(Assembly.GetEntryAssembly); private static readonly Lazy CompanyNameLazy = new Lazy(() => { var attribute = EntryAssembly.GetCustomAttribute(typeof(AssemblyCompanyAttribute)) as AssemblyCompanyAttribute; return attribute?.Company ?? string.Empty; }); private static readonly Lazy ProductNameLazy = new Lazy(() => { var attribute = EntryAssembly.GetCustomAttribute(typeof(AssemblyProductAttribute)) as AssemblyProductAttribute; return attribute?.Product ?? string.Empty; }); private static readonly Lazy ProductTrademarkLazy = new Lazy(() => { var attribute = EntryAssembly.GetCustomAttribute(typeof(AssemblyTrademarkAttribute)) as AssemblyTrademarkAttribute; return attribute?.Trademark ?? string.Empty; }); private static readonly string ApplicationMutexName = "Global\\{{" + EntryAssembly.FullName + "}}"; private static readonly object SyncLock = new object(); private static OperatingSystem? _oS; #region Properties /// /// Gets the current Operating System. /// /// /// The os. /// public static OperatingSystem OS { get { if (_oS.HasValue == false) { var windowsDirectory = Environment.GetEnvironmentVariable("windir"); if (string.IsNullOrEmpty(windowsDirectory) == false && windowsDirectory.Contains(@"\") && Directory.Exists(windowsDirectory)) { _oS = OperatingSystem.Windows; } else { _oS = File.Exists(@"/proc/sys/kernel/ostype") ? OperatingSystem.Unix : OperatingSystem.Osx; } } return _oS ?? OperatingSystem.Unknown; } } /// /// Checks if this application (including version number) is the only instance currently running. /// /// /// true if this instance is the only instance; otherwise, false. /// public static bool IsTheOnlyInstance { get { lock (SyncLock) { try { // Try to open existing mutex. Mutex.OpenExisting(ApplicationMutexName); } catch { try { // If exception occurred, there is no such mutex. var appMutex = new Mutex(true, ApplicationMutexName); $"Application Mutex created {appMutex} named '{ApplicationMutexName}'".Debug( typeof(SwanRuntime)); // Only one instance. return true; } catch { // Sometimes the user can't create the Global Mutex } } // More than one instance. return false; } } } /// /// Gets a value indicating whether this application instance is using the MONO runtime. /// /// /// true if this instance is using MONO runtime; otherwise, false. /// public static bool IsUsingMonoRuntime => Type.GetType("Mono.Runtime") != null; /// /// Gets the assembly that started the application. /// /// /// The entry assembly. /// public static Assembly EntryAssembly => EntryAssemblyLazy.Value; /// /// Gets the name of the entry assembly. /// /// /// The name of the entry assembly. /// public static AssemblyName EntryAssemblyName => EntryAssemblyLazy.Value.GetName(); /// /// Gets the entry assembly version. /// public static Version EntryAssemblyVersion => EntryAssemblyName.Version; /// /// Gets the full path to the folder containing the assembly that started the application. /// /// /// The entry assembly directory. /// public static string EntryAssemblyDirectory { get { var uri = new UriBuilder(EntryAssembly.CodeBase); var path = Uri.UnescapeDataString(uri.Path); return Path.GetDirectoryName(path); } } /// /// Gets the name of the company. /// /// /// The name of the company. /// public static string CompanyName => CompanyNameLazy.Value; /// /// Gets the name of the product. /// /// /// The name of the product. /// public static string ProductName => ProductNameLazy.Value; /// /// Gets the trademark. /// /// /// The product trademark. /// public static string ProductTrademark => ProductTrademarkLazy.Value; /// /// Gets a local storage path with a version. /// /// /// The local storage path. /// public static string LocalStoragePath { get { var localAppDataPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), EntryAssemblyName.Name); var returnPath = Path.Combine(localAppDataPath, EntryAssemblyVersion.ToString()); if (!Directory.Exists(returnPath)) { Directory.CreateDirectory(returnPath); } return returnPath; } } #endregion #region Methods /// /// Build a full path pointing to the current user's desktop with the given filename. /// /// The filename. /// /// The fully qualified location of path, such as "C:\MyFile.txt". /// /// filename. public static string GetDesktopFilePath(string filename) { if (string.IsNullOrWhiteSpace(filename)) throw new ArgumentNullException(nameof(filename)); var pathWithFilename = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory), filename); return Path.GetFullPath(pathWithFilename); } #endregion } }