/// <summary>
        /// Update the current application
        /// </summary>
        public static void PerformUpdate(Options options, ColorScheme colorScheme)
        {
            try
            {
                // download the update
                // replace the current exe
                // relaunch
                var filename = Path.Combine(Path.GetTempPath(), "NUnit.Commander\\NUnit.Commander.msi");
                Directory.CreateDirectory(Path.GetDirectoryName(filename));

                // this won't work with .net core single file publishing
                //var assemblyFile = Assembly.GetExecutingAssembly().Location;
                var currentProcess = Process.GetCurrentProcess();
                var assemblyFile   = currentProcess.MainModule.FileName;
#if DEBUG
                var assemblyArgs = Environment.CommandLine.Replace(assemblyFile.Replace(".exe", ".dll"), "");
#else
                var assemblyArgs = Environment.CommandLine.Replace(assemblyFile, "");
#endif
                var assemblyPath     = Path.GetDirectoryName(assemblyFile);
                var assemblyTempFile = $"{assemblyFile}.tmp";
                var client           = new HttpClient();
                var percentageX      = 0;
                if (!Console.IsOutputRedirected)
                {
                    Console.CursorVisible = false;
                    Console.Write($"Downloading v{LatestVersion.ToString()} update... ");
                    percentageX = Console.CursorLeft;
                }
                Task.Run(async() =>
                {
                    var response    = await client.GetAsync($"https://github.com/replaysMike/NUnit.Commander/releases/latest/download/NUnit.Commander.msi", HttpCompletionOption.ResponseHeadersRead);
                    var stream      = await response.Content.ReadAsStreamAsync();
                    var totalLength = response.Content.Headers.ContentLength;
                    var buffer      = new byte[512 * 1024]; // 512kb buffer
                    int bytesRead;
                    var streamWriter = new FileStream(filename, FileMode.Create);
                    do
                    {
                        bytesRead = await stream.ReadAsync(buffer, 0, buffer.Length);
                        streamWriter.Write(buffer, 0, bytesRead);
                        var percDone = ((double)streamWriter.Length / totalLength) * 100.0;
                        if (!Console.IsOutputRedirected)
                        {
                            Console.SetCursorPosition(percentageX, Console.CursorTop);
                            Console.Write($"{percDone:n0}%     ", colorScheme.Duration);
                        }
                    } while (bytesRead > 0);
                    streamWriter.Close();
                    streamWriter.Dispose();
                    if (!Console.IsOutputRedirected)
                    {
                        Console.WriteLine($"{Environment.NewLine}Download complete.     ", colorScheme.Duration);
                    }
                }).GetAwaiter().GetResult();

                if (!Console.IsOutputRedirected)
                {
                    Console.Write($"Installing v{LatestVersion.ToString()} update ({assemblyPath})... ");
                }

                // rename the current assembly
                if (File.Exists(assemblyTempFile))
                {
                    File.Delete(assemblyTempFile);
                }
                File.Move(assemblyFile, assemblyTempFile);

                var process = new Process();
                process.StartInfo.FileName         = "msiexec";
                process.StartInfo.WorkingDirectory = Path.GetTempPath();
                process.StartInfo.Arguments        = $"/passive /norestart /i {filename} INSTALLFOLDER={assemblyPath}";
                // To enable msi installation logging use: /log c:\\logs\\commander-msi-install.log
                process.StartInfo.Verb = "runas";
                process.Start();
                //var exited = process.WaitForExit(30 * 1000);

                if (!Console.IsOutputRedirected)
                {
                    Console.WriteLine($"done!");
                    if (options.Relaunch)
                    {
                        // relaunch application with same arguments. Note this will be out of process
                        try
                        {
                            var relaunchProcess = new Process();
                            relaunchProcess.StartInfo.FileName  = assemblyFile;
                            relaunchProcess.StartInfo.Arguments = assemblyArgs;
                            relaunchProcess.Start();
                        }
                        catch (Exception ex)
                        {
                            Console.WriteLine($"Failed to restart application automatically. Please re-launch application manually. Error: {ex.Message}");
                        }
                    }
                    // start a new process with a slight delay to cleanup our temp assembly file
                    Process.Start(new ProcessStartInfo()
                    {
                        Arguments      = "/C choice /C Y /N /D Y /T 2 & Del \"" + assemblyTempFile + "\"",
                        WindowStyle    = ProcessWindowStyle.Hidden,
                        CreateNoWindow = true,
                        FileName       = "cmd.exe"
                    });

                    // return success updated
                    Environment.Exit((int)ExitCode.ApplicationUpdated);
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine($"Failed to update application. {ex.Message}");
                // continue with run
            }
        }
示例#2
0
            static void DisplayInitializationScreen(Options options, ApplicationConfiguration config, ColorScheme colorScheme, RunContext runContext)
            {
                // initialize the performance counters before launching the test runner
                // this is because it can be slow, we don't want to delay connecting to the test runner
                try
                {
                    if (!Console.IsOutputRedirected)
                    {
                        var currentFont = ConsoleUtil.GetCurrentFont().FontName;
                        Console.Write($"Console font: ");
                        Console.WriteLine(currentFont, colorScheme.DarkDefault);
                        var unicodeTestHeader = "Unicode test:";
                        Console.Write(unicodeTestHeader);
                        Console.WriteLine("\u2022 ╭╮╰╯═══\u2801\u2802\u2804\u2840\u28FF", colorScheme.DarkDefault);
                        var conEmuDetected     = !string.IsNullOrEmpty(Environment.GetEnvironmentVariable("ConEmuPID"));
                        var parentProcess      = ParentProcessUtilities.GetParentProcess();
                        var powershellDetected = parentProcess?.ProcessName.Equals("powershell", StringComparison.InvariantCultureIgnoreCase) == true;
                        var dotChar            = ConsoleUtil.GetCharAt(unicodeTestHeader.Length, Console.CursorTop);     // dot ok
                        var brailleChar        = ConsoleUtil.GetCharAt(unicodeTestHeader.Length + 9, Console.CursorTop); // braille ok
                        var dotCharOk          = false;
                        if (OperatingSystem.IsWindows())
                        {
                            dotCharOk = ConsoleUtil.CheckIfCharInFont(dotChar, new Font(currentFont, 10));
                        }

                        var brailleCharOk = false;
                        if (OperatingSystem.IsWindows())
                        {
                            brailleCharOk = ConsoleUtil.CheckIfCharInFont(brailleChar, new Font(currentFont, 10));
                        }
                        // Console.WriteLine($"Dot: {dotCharOk}, Braille: {brailleCharOk}");
                        Console.Write($"Console Detection: ");
                        if (conEmuDetected)
                        {
                            Console.WriteLine("ConEmu", colorScheme.DarkDefault);
                            config.DisplayConfiguration.IsConEmuDetected        = true;
                            config.DisplayConfiguration.SupportsExtendedUnicode = true;
                        }
                        else if (powershellDetected)
                        {
                            Console.WriteLine("Powershell", colorScheme.DarkDefault);
                            config.DisplayConfiguration.IsPowershellDetected = true;
                        }
                        else
                        {
                            Console.WriteLine("Command Prompt", colorScheme.DarkDefault);
                            config.DisplayConfiguration.IsCommandPromptDetected = true;
                        }
                    }
                    Console.Write($"Test runner arguments: ");
                    Console.WriteLine(options.TestRunnerArguments.MaxLength(360), colorScheme.DarkDefault);

                    Console.WriteLine($"Initializing performance counters...", colorScheme.Default);
                    if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
                    {
#pragma warning disable CA1416 // Validate platform compatibility
                        runContext.PerformanceCounters.CpuCounter  = new PerformanceCounter("Processor", "% Processor Time", "_Total");
                        runContext.PerformanceCounters.DiskCounter = new PerformanceCounter("PhysicalDisk", "% Disk Time", "_Total");
#pragma warning restore CA1416 // Validate platform compatibility
                    }
                }
                catch (Exception ex)
                {
                    Console.WriteLine($"Error initializing performance counters... {ex.Message}", colorScheme.Error);
                    // unable to use performance counters.
                    // possibly need to run C:\Windows\SysWOW64> lodctr /r
                }
            }