예제 #1
0
        /// <summary>
        /// The warn user on load.
        /// </summary>
        /// <returns>
        /// The list of temporary files generated
        /// </returns>
        private static List <string> DownloadAndNotifyUser(ChromelyPlatform platform)
        {
            var tempFiles = new List <string>();

            try
            {
                var stopwatch = new Stopwatch();
                stopwatch.Start();

                var startTempFile = ShowDownloadStartedPage();
                tempFiles.Add(startTempFile);

                CefLoader.Download(platform);

                stopwatch.Stop();
                var competedTempFile = ShowDownloadCompletedPage($"Time elapsed: {stopwatch.Elapsed}.");

                if (competedTempFile != null)
                {
                    tempFiles.Add(competedTempFile);
                }

                Thread.Sleep(TimeSpan.FromSeconds(2));
            }
            catch (Exception ex)
            {
                Logger.Instance.Log.LogError(ex, ex.Message);
                var onErrorTempFile = ShowErrorPage(ex);
                tempFiles.Add(onErrorTempFile);
                Environment.Exit(0);
            }

            return(tempFiles);
        }
예제 #2
0
        /// <summary>
        /// The warn user on load.
        /// </summary>
        /// <returns>
        /// The list of temporary files generated
        /// </returns>
        private static List <string> WarnUserOnLoad(ChromelyPlatform platform)
        {
            var tempFiles = new List <string>();

            try
            {
                var stopwatch = new Stopwatch();
                stopwatch.Start();

                var startTempFile = LaunchStartPage();
                tempFiles.Add(startTempFile);

                CefLoader.Load(platform);

                stopwatch.Stop();
                var competedTempFile = LaunchCompletedPage($"Time elapsed: {stopwatch.Elapsed}.");

                if (competedTempFile != null)
                {
                    tempFiles.Add(competedTempFile);
                }

                Thread.Sleep(TimeSpan.FromSeconds(2));
            }
            catch (Exception ex)
            {
                Log.Error(ex);
                var onErrorTempFile = LaunchErrorPage(ex);
                tempFiles.Add(onErrorTempFile);
                Environment.Exit(0);
            }

            return(tempFiles);
        }
예제 #3
0
        public static void LoadNativeGuiFile(ChromelyPlatform chromelyPlatform)
        {
            if (chromelyPlatform != ChromelyPlatform.MacOSX)
            {
                return;
            }

            var    appDirectory      = AppDomain.CurrentDomain.BaseDirectory;
            string fullPathNativeDll = Path.Combine(appDirectory, MacOSNativeDllFile);

            if (File.Exists(fullPathNativeDll))
            {
                return;
            }

            Task.Run(() =>
            {
                string resourcePath = $"Chromely.Native.mac.{MacOSNativeDllFile}";
                using (var resource = Assembly.GetExecutingAssembly().GetManifestResourceStream(resourcePath))
                {
                    using (var file = new FileStream(fullPathNativeDll, FileMode.Create, FileAccess.Write))
                    {
                        resource?.CopyTo(file);
                    }
                }
            });
        }
예제 #4
0
    /// <summary>
    /// Checks if process or subprocess is allowed to execute based on the OS platform.
    /// </summary>
    /// <param name="platform">The OS platorm.</param>
    /// <param name="args">Command line arguments.</param>
    /// <returns>true if allowed, otherwise false.</returns>
    public static bool IsProcessExecutionAllowed(ChromelyPlatform platform, IEnumerable <string> args)
    {
        if (platform != ChromelyPlatform.MacOSX)
        {
            return(true);
        }

        return(HasArgument(args, ArgumentType));
    }
예제 #5
0
        private CefLoader()
        {
            _platform     = ChromelyRuntime.Platform;
            _architecture = RuntimeInformation.ProcessArchitecture;
            _build        = ChromelyRuntime.GetExpectedChromiumBuildNumber(ChromelyCefWrapper.CefGlue);
            Log.Info($"CefLoader: Load CEF for {_platform} {_architecture}, version {_build}");

            _lastPercent = 0;
            _numberOfParallelDownloads = Environment.ProcessorCount;

            _tempBz2File   = Path.GetTempFileName();
            _tempTarFile   = Path.GetTempFileName();
            _tempDirectory = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
        }
예제 #6
0
        /// <summary>
        /// Download CEF runtime files.
        /// </summary>
        /// <exception cref="Exception"></exception>
        public static void Download(ChromelyPlatform platform)
        {
            Logger.Instance.Log.LogInformation("CefLoader: Installing CEF runtime from " + CefBuildsDownloadUrl);

            var loader = new CefLoader(platform);

            try
            {
                var watch = new Stopwatch();
                watch.Start();
                loader.GetDownloadUrl();
                if (!loader.ParallelDownload())
                {
                    loader.Download();
                }
                Logger.Instance.Log.LogInformation($"CefLoader: Download took {watch.ElapsedMilliseconds}ms");
                watch.Restart();
                loader.DecompressArchive();
                Logger.Instance.Log.LogInformation($"CefLoader: Decompressing archive took {watch.ElapsedMilliseconds}ms");
                watch.Restart();
                loader.CopyFilesToAppDirectory();
                Logger.Instance.Log.LogInformation($"CefLoader: Copying files took {watch.ElapsedMilliseconds}ms");
            }
            catch (Exception ex)
            {
                Logger.Instance.Log.LogError("CefLoader: " + ex.Message);
                throw;
            }
            finally
            {
                if (!string.IsNullOrEmpty(loader._tempBz2File))
                {
                    File.Delete(loader._tempBz2File);
                }

                if (!string.IsNullOrEmpty(loader._tempTarStream))
                {
                    File.Delete(loader._tempTarStream);
                }

                if (!string.IsNullOrEmpty(loader._tempTarFile))
                {
                    File.Delete(loader._tempTarFile);
                }
                if (!string.IsNullOrEmpty(loader._tempDirectory) && Directory.Exists(loader._tempDirectory))
                {
                    Directory.Delete(loader._tempDirectory, true);
                }
            }
        }
예제 #7
0
        private CefLoader(ChromelyPlatform platform)
        {
            _platform     = platform;
            _architecture = RuntimeInformation.ProcessArchitecture;
            _build        = ChromelyRuntime.GetExpectedCefBuild();
            Logger.Instance.Log.LogInformation($"CefLoader: Load CEF for {_platform} {_architecture}, version {_build}");

            _lastPercent = 0;
            _numberOfParallelDownloads = Environment.ProcessorCount;

            _tempTarStream = Path.GetTempFileName();
            _tempBz2File   = Path.GetTempFileName();
            _tempTarFile   = Path.GetTempFileName();
            _tempDirectory = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
        }
예제 #8
0
        public static void Open(ChromelyPlatform platform, string url)
        {
            try
            {
                try
                {
                    Process.Start(url);
                }
                catch
                {
                    try
                    {
                        // hack because of this: https://github.com/dotnet/corefx/issues/10361
                        switch (platform)
                        {
                        case ChromelyPlatform.Windows:
                            url = url.Replace("&", "^&");
                            Process.Start(new ProcessStartInfo("cmd", $"/c start {url}")
                            {
                                CreateNoWindow = true
                            });
                            break;

                        case ChromelyPlatform.Linux:
                            Process.Start("xdg-open", url);
                            break;

                        case ChromelyPlatform.MacOSX:
                            Process.Start("open", url);
                            break;

                        default:
                            Process.Start(url);
                            break;
                        }
                    }
                    catch (Exception exception)
                    {
                        Logger.Instance.Log.Error(exception);
                    }
                }
            }
            catch (Exception exception)
            {
                Logger.Instance.Log.Error(exception);
            }
        }
예제 #9
0
        public DynamicCefLoader(IServiceProvider serviceProvider)
        {
            _logger   = serviceProvider.GetService <ILogger>();
            _platform = serviceProvider.GetService <IChromelyConfiguration>().Platform;

            _architecture = RuntimeInformation.ProcessArchitecture;
            _build        = ChromelyRuntime.GetExpectedCefBuild();
            _logger?.LogInformation($"CefLoader: Load CEF for {_platform} {_architecture}, version {_build}");

            _lastPercent = 0;
            _numberOfParallelDownloads = Environment.ProcessorCount;

            _tempTarStream = Path.GetTempFileName();
            _tempBz2File   = Path.GetTempFileName();
            _tempTarFile   = Path.GetTempFileName();
            _tempDirectory = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
        }
예제 #10
0
        public static INativeGui GetNativeGui(ChromelyPlatform chromelyPlatform)
        {
            switch (chromelyPlatform)
            {
            case ChromelyPlatform.MacOSX:
                return(new MacNativeGui());

            case ChromelyPlatform.Linux:
                return(new LinuxNativeGui());

            case ChromelyPlatform.Windows:
                return(new WinNativeGui());

            default:
                return(new WinNativeGui());
            }
        }
예제 #11
0
        public static IChromelyConfiguration CreateConfigurationForPlatform(ChromelyPlatform platform)
        {
            IChromelyConfiguration config;

            try
            {
                config = new DefaultConfiguration();

                switch (platform)
                {
                case ChromelyPlatform.Windows:
                    config.WindowOptions.CustomStyle    = new WindowCustomStyle(0, 0);
                    config.WindowOptions.UseCustomStyle = false;
                    break;

                case ChromelyPlatform.Linux:
                    config.CommandLineArgs = new Dictionary <string, string>
                    {
                        ["disable-gpu"] = "1"
                    };

                    config.CommandLineOptions = new List <string>()
                    {
                        "no-zygote",
                        "disable-gpu",
                        "disable-software-rasterizer"
                    };
                    break;

                case ChromelyPlatform.MacOSX:
                    break;
                }

                return(config);
            }
            catch (Exception exception)
            {
                config = null;
                Logger.Instance.Log.Error(exception);
            }

            return(config);
        }
        public static string GetSettingsFilePath(ChromelyPlatform platform, string appName = "chromely", bool onSave = false)
        {
            try
            {
                var appSettingsDir = string.Empty;
                var fileName       = $"{appName}_appsettings.config";

                switch (platform)
                {
                case ChromelyPlatform.Windows:
                    appSettingsDir = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData, Environment.SpecialFolderOption.DoNotVerify), "chromely");
                    break;

                case ChromelyPlatform.Linux:
                    appSettingsDir = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData, Environment.SpecialFolderOption.DoNotVerify), "chromely");
                    break;

                case ChromelyPlatform.MacOSX:
                    appSettingsDir = Environment.GetFolderPath(Environment.SpecialFolder.Personal, Environment.SpecialFolderOption.DoNotVerify);
                    appSettingsDir = appSettingsDir.Replace("/Documents", "/Library/Application Support/chromely/");
                    break;
                }

                if (onSave)
                {
                    Directory.CreateDirectory(appSettingsDir);
                    if (Directory.Exists(appSettingsDir))
                    {
                        return(Path.Combine(appSettingsDir, fileName));
                    }
                }
                else
                {
                    return(Path.Combine(appSettingsDir, fileName));
                }
            }
            catch (Exception exception)
            {
                Logger.Instance.Log.LogError(exception, exception.Message);
            }

            return(null);
        }
예제 #13
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="platform"></param>
        /// <param name="processArchitecture"></param>
        /// <param name="build"></param>
        /// <returns></returns>
        public string FindCefArchiveName(ChromelyPlatform platform, Architecture processArchitecture, CefBuildNumbers build)
        {
            var arch = processArchitecture.ToString()
                       .Replace("X64", "64")
                       .Replace("X86", "32");
            var platformIdentifier = (platform + arch).ToLower();
            var indexUrl           = CefBuildsDownloadIndex(platformIdentifier);

            // cef_binary_3.3626.1895.g7001d56_windows64_client.tar.bz2
            var binaryNamePattern1 = $@"""(cef_binary_[0-9]+\.{build}\.[0-9]+\.(.*)_{platformIdentifier}_client.tar.bz2)""";

            // cef_binary_73.1.5+g4a68f1d+chromium-73.0.3683.75_windows64_client.tar.bz2
            // cef_binary_77.1.18+g8e8d602+chromium-77.0.3865.120_windows64_client.tar.bz2
            var versionPattern     = build.CefVersion.Replace("+", "%2B");
            var binaryNamePattern2 = $@"""(cef_binary_{versionPattern}_{platformIdentifier}_minimal.tar.bz2)""";

            using (var client = new WebClient())
            {
                Logger.Instance.Log.Info($"CefLoader: Load index page {indexUrl}");
                var cefIndex = client.DownloadString(indexUrl);

                // up to Chromium version 72
                var found = new Regex(binaryNamePattern1, RegexOptions.CultureInvariant | RegexOptions.IgnoreCase).Match(cefIndex);
                if (found.Success)
                {
                    return(found.Groups[1].Value);
                }
                // from Chromium version 73 up
                found = new Regex(binaryNamePattern2, RegexOptions.CultureInvariant | RegexOptions.IgnoreCase).Match(cefIndex);
                if (found.Success)
                {
                    return(found.Groups[1].Value);
                }

                var message = $"CEF for chrome version {CefRuntime.ChromeVersion} platform {platformIdentifier} not found.";
                Logger.Instance.Log.Fatal("CefLoader: " + message);
            }

            return("");
        }
예제 #14
0
        /// <summary>Load Cef binaries</summary>
        /// <param name="options">The config.</param>
        /// <param name="chromelyPlatform">The chromely platform.</param>
        /// <returns>The list of temporary files generated</returns>
        public static List <string> Load(ICefDownloadOptions options, ChromelyPlatform chromelyPlatform)
        {
            try
            {
                var platform = CefRuntime.Platform;
                var version  = CefRuntime.ChromeVersion;
                Logger.Instance.Log.Info($"Running {platform} chromium {version}");

                try
                {
                    CefRuntime.Load();
                }
                catch (Exception ex)
                {
                    Logger.Instance.Log.Error(ex);
                    if (options.AutoDownloadWhenMissing)
                    {
                        if (options.DownloadSilently)
                        {
                            CefLoader.Download(chromelyPlatform);
                        }
                        else
                        {
                            return(DownloadAndNotifyUser(chromelyPlatform));
                        }
                    }
                    else
                    {
                        Environment.Exit(0);
                    }
                }
            }
            catch (Exception ex)
            {
                Logger.Instance.Log.Error(ex);
                Environment.Exit(0);
            }

            return(null);
        }
예제 #15
0
        public static void EnsureNativeGuiFileExists(ChromelyPlatform chromelyPlatform)
        {
            if (chromelyPlatform != ChromelyPlatform.MacOSX)
            {
                return;
            }

            var    appDirectory      = AppDomain.CurrentDomain.BaseDirectory;
            string fullPathNativeDll = Path.Combine(appDirectory, MacOSNativeDllFile);

            var timeout = DateTime.Now.Add(TimeSpan.FromSeconds(30));

            while (!File.Exists(fullPathNativeDll))
            {
                if (DateTime.Now > timeout)
                {
                    Log.Error($"File {fullPathNativeDll} does not exist.");
                    return;
                }

                Thread.Sleep(TimeSpan.FromSeconds(5));
            }
        }
예제 #16
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="platform"></param>
        /// <param name="processArchitecture"></param>
        /// <param name="build"></param>
        /// <returns></returns>
        public static string FindCefArchiveName(ChromelyPlatform platform, Architecture processArchitecture, int build)
        {
            var arch = processArchitecture.ToString()
                       .Replace("X64", "64")
                       .Replace("X86", "32");
            var platformIdentifier = platform.ToString().ToLower() + arch;
            var indexUrl           = CefBuildsDownloadIndex(platformIdentifier);

            // cef_binary_3.3626.1895.g7001d56_windows64_client.tar.bz2
            var binaryNamePattern1 = $@"""(cef_binary_[0-9]+\.{build}\.[0-9]+\.(.*)_{platformIdentifier}_client.tar.bz2)""";

            // cef_binary_73.1.5+g4a68f1d+chromium-73.0.3683.75_windows64_client.tar.bz2
            var binaryNamePattern2 = $@"""(cef_binary_.*\+chromium\-[0-9]+\.[0-9]+\.{build}\.[0-9]_{platformIdentifier}_client.tar.bz2)""";

            using (var client = new WebClient())
            {
                Log.Info($"CefLoader: Load index page {indexUrl}");
                var cefIndex = client.DownloadString(indexUrl);
                // up to Chromium version 72
                var found = new Regex(binaryNamePattern1).Match(cefIndex);
                if (found.Success)
                {
                    return(found.Groups[1].Value);
                }
                // from Chromium version 73 up
                found = new Regex(binaryNamePattern2).Match(cefIndex);
                if (found.Success)
                {
                    return(found.Groups[1].Value);
                }

                var message = $"CEF for chrome version {CefRuntime.ChromeVersion} platform {platformIdentifier} not found.";
                Log.Fatal("CefLoader: " + message);
            }

            return("");
        }
예제 #17
0
        public static IChromelyConfiguration CreateOSDefault(ChromelyPlatform platform)
        {
            IChromelyConfiguration config;

            try
            {
                config          = new DefaultConfiguration();
                config.AppName  = "chromely_demo";
                config.StartUrl = "local://app/chromely.html";
                config.LoadCefBinariesIfNotFound = true;
                config.SilentCefBinariesLoading  = false;
                config.WindowLeft          = 0;
                config.WindowTop           = 0;
                config.WindowWidth         = 1200;
                config.WindowHeight        = 900;
                config.WindowNoResize      = false;
                config.WindowNoMinMaxBoxes = false;
                config.WindowFrameless     = false;
                config.WindowCenterScreen  = true;
                config.WindowKioskMode     = false;
                config.WindowState         = WindowState.Normal;
                config.WindowTitle         = "chromely";
                config.WindowIconFile      = "chromely.ico";
                config.DebuggingMode       = true;

                config.UrlSchemes = new List <UrlScheme>();
                var schemeDefaultResource = new UrlScheme("default-resource", "local", string.Empty, string.Empty, UrlSchemeType.Resource, false);
                var schemeCustomHttp      = new UrlScheme("default-custom-http", "http", "chromely.com", string.Empty, UrlSchemeType.Custom, false);
                var schemeCommandHttp     = new UrlScheme("default-command-http", "http", "command.com", string.Empty, UrlSchemeType.Command, false);
                var schemeExternal1       = new UrlScheme("chromely-site", string.Empty, string.Empty, "https://github.com/chromelyapps/Chromely", UrlSchemeType.External, true);

                config.UrlSchemes.Add(schemeDefaultResource);
                config.UrlSchemes.Add(schemeCustomHttp);
                config.UrlSchemes.Add(schemeCommandHttp);
                config.UrlSchemes.Add(schemeExternal1);

                config.ControllerAssemblies = new List <ControllerAssemblyInfo>();
                config.ControllerAssemblies.RegisterServiceAssembly("Chromely.External.Controllers.dll");

                config.CustomSettings = new Dictionary <string, string>();
                config.CustomSettings["cefLogFile"]  = "logs\\chromely.cef.log";
                config.CustomSettings["logSeverity"] = "info";
                config.CustomSettings["locale"]      = "en-US";

                switch (platform)
                {
                case ChromelyPlatform.Windows:
                    config.WindowCustomStyle    = new WindowCustomStyle(0, 0);
                    config.UseWindowCustomStyle = false;
                    break;

                case ChromelyPlatform.Linux:
                    config.CommandLineArgs = new Dictionary <string, string>();
                    config.CommandLineArgs["disable-gpu"] = "1";

                    config.CommandLineOptions = new List <string>();
                    config.CommandLineOptions.Add("no-zygote");
                    config.CommandLineOptions.Add("disable-gpu");
                    config.CommandLineOptions.Add("disable-software-rasterizer");
                    break;

                case ChromelyPlatform.MacOSX:
                    break;
                }

                return(config);
            }
            catch (Exception exception)
            {
                config = null;
                Logger.Instance.Log.Error(exception);
            }

            return(config);
        }
예제 #18
0
        public static void Resize(ChromelyPlatform chromelyPlatform, IntPtr window, int width, int height)
        {
            var nativeGui = NativeGuiFactory.GetNativeGui(chromelyPlatform);

            nativeGui.ResizeWindow(window, width, height);
        }
예제 #19
0
        public static void MessageBox(ChromelyPlatform chromelyPlatform, string message, MessageType messageType = MessageType.Error)
        {
            var nativeGui = NativeGuiFactory.GetNativeGui(chromelyPlatform);

            nativeGui.MessageBox(message, messageType);
        }
예제 #20
0
        public static void Quit(ChromelyPlatform chromelyPlatform)
        {
            var nativeGui = NativeGuiFactory.GetNativeGui(chromelyPlatform);

            nativeGui.Quit();
        }
예제 #21
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="platform"></param>
        /// <param name="processArchitecture"></param>
        /// <param name="build"></param>
        /// <returns></returns>
        public string FindCefArchiveName(ChromelyPlatform platform, Architecture processArchitecture, CefBuildNumbers build)
        {
            var arch = processArchitecture.ToString()
                       .Replace("X64", "64")
                       .Replace("X86", "32");
            var platformIdentifier = (platform + arch).ToLower();
            var indexUrl           = CefBuildsDownloadIndex(platformIdentifier);

            // cef_binary_3.3626.1895.g7001d56_windows64_client.tar.bz2
            var binaryNamePattern1 = $@"""(cef_binary_[0-9]+\.{build}\.[0-9]+\.(.*)_{platformIdentifier}_client.tar.bz2)""";

            // cef_binary_73.1.5+g4a68f1d+chromium-73.0.3683.75_windows64_client.tar.bz2
            // cef_binary_77.1.18+g8e8d602+chromium-77.0.3865.120_windows64_client.tar.bz2
            var versionPattern     = build.CefVersion.Replace("+", "%2B");
            var binaryNamePattern2 = $@"""(cef_binary_{versionPattern}_{platformIdentifier}_minimal.tar.bz2)""";

            using (var client = new WebClient())
            {
                Logger.Instance.Log.LogInformation($"CefLoader: Load index page {indexUrl}");
                var cefIndex = client.DownloadString(indexUrl);

                // up to Chromium version 72
                var found = new Regex(binaryNamePattern1, RegexOptions.CultureInvariant | RegexOptions.IgnoreCase).Match(cefIndex);
                if (found.Success)
                {
                    return(found.Groups[1].Value);
                }
                // from Chromium version 73 up
                found = new Regex(binaryNamePattern2, RegexOptions.CultureInvariant | RegexOptions.IgnoreCase).Match(cefIndex);
                if (found.Success)
                {
                    return(found.Groups[1].Value);
                }

                #region https://github.com/chromelyapps/Chromely/issues/257

                // Hack until fixed.
                if (!string.IsNullOrEmpty(binaryNamePattern1))
                {
                    if (binaryNamePattern1.Contains("83.0.4103.106"))
                    {
                        return($"cef_binary_83.5.0%2Bgbf03589%2Bchromium-83.0.4103.106_{platformIdentifier}_minimal.tar.bz2");
                    }
                }

                if (!string.IsNullOrEmpty(binaryNamePattern2))
                {
                    if (binaryNamePattern2.Contains("83.0.4103.106"))
                    {
                        return($"cef_binary_83.5.0%2Bgbf03589%2Bchromium-83.0.4103.106_{platformIdentifier}_minimal.tar.bz2");
                    }
                }

                #endregion Hack until fixed.

                var message = $"CEF for chrome version {CefRuntime.ChromeVersion} platform {platformIdentifier} not found.";
                Logger.Instance.Log.LogError("CefLoader: " + message);
            }

            return("");
        }