Inheritance: IAppUninstaller
        internal DebugWindow(MainWindow reference, UninstallerListViewUpdater listview, AppUninstaller appUninstaller)
        {
            _reference      = reference;
            _listView       = listview;
            _appUninstaller = appUninstaller;

            InitializeComponent();

            _settings.Subscribe(TestHandler, x => x.FilterHideMicrosoft, this);
            _settings.BindControl(checkBox1, x => x.FilterHideMicrosoft, this);

            _settings.BindControl(checkBoxDebug, x => x.Debug, this);
            checkBoxDebug.Checked = Settings.Default.Debug;

            var messageboxes = typeof(MessageBoxes)
                               .GetMethods(BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public);

            foreach (var x in messageboxes)
            {
                var wr = new ComboBoxWrapper <MethodInfo>(x, y =>
                {
                    var name = y.ToString();
                    return(name.Substring(name.IndexOf(' ') + 1));
                });
                comboBoxMessages.Items.Add(wr);
            }

            checkBox2.Checked = Program.IsInstalled;
        }
Example #2
0
        private void buttonSort_Click(object sender, EventArgs e)
        {
            objectListView1.PrimarySortColumn = null;
            var results = AppUninstaller.SortIntelligently(Entries, entry => entry.Entry);

            objectListView1.SetObjects(results.ToList());
        }
Example #3
0
        public AppUninstallerTests()
        {
            _mainLog = new Mock <ILog>();

            _processManager = new Mock <IMlaunchProcessManager>();
            _processManager.SetReturnsDefault(Task.FromResult(new ProcessExecutionResult()
            {
                ExitCode = 0
            }));

            _appUninstaller = new AppUninstaller(_processManager.Object, _mainLog.Object, 1);
        }
        private void UpdateState()
        {
            UseWaitCursor = true;
            Application.DoEvents();

            switch (PageNumber)
            {
            case 0:
                break;

            case 1:
            {
                processWaiterControl1.StopUpdating();

                var additionals = relatedUninstallerAdder1.GetResults();
                var taskEntries = ConvertToTaskEntries(_selectedUninstallers.Concat(additionals));
                taskEntries = SortTaskEntryList(taskEntries);
                uninstallConfirmation1.SetRelatedApps(taskEntries);
            }
            break;

            case 2:
            {
                /*if (taskEntries == null || taskEntries.Count == 0) return;*/

                var selectedTaskEntries = uninstallConfirmation1.GetResults().ToList();

                if (!selectedTaskEntries.Any())
                {
                    MessageBoxes.NoUninstallersSelectedInfo();

                    PageNumber = 1;
                    return;
                }

                var relatedPids = AppUninstaller.GetRelatedProcessIds(
                    selectedTaskEntries.Select(x => x.UninstallerEntry), !_quiet);

                if (relatedPids.Length == 0)
                {
                    PageNumber = _previousPageNumber < 2 ? 3 : 1;
                    return;
                }

                processWaiterControl1.Initialize(relatedPids, !_quiet);
                processWaiterControl1.StartUpdating();
            }
            break;

            case 3:     // Settings
                processWaiterControl1.StopUpdating();
                break;

            case 4:     // Final
            {
                var taskEntries = uninstallConfirmation1.GetResults().ToList();

                labelApps.Text = string.Join(", ",
                                             taskEntries.Select(x => x.UninstallerEntry.DisplayName).OrderBy(x => x).ToArray());
                labelTotalSize.Text = FileSize.SumFileSizes(taskEntries.Select(x => x.UninstallerEntry.EstimatedSize)).ToString();

                labelConcurrentEnabled.Text   = Settings.Default.UninstallConcurrency.ToYesNo();
                labelFilesStillUsed.Text      = processWaiterControl1.ProcessesStillRunning.ToYesNo();
                labelRestorePointCreated.Text = (Settings.Default.CreateRestorePoint && SysRestore.SysRestoreAvailable()).ToYesNo();
                labelWillBeSilent.Text        = _quiet.ToYesNo();

                labelOther.Text = Settings.Default.AdvancedSimulate ? "Simulating" : "-";
            }
            break;
            }

            labelProgress.Text = PageNumber + 1 + " / " + tabControl1.TabCount;
            buttonPrev.Enabled = PageNumber > 0 && (PageNumber != 1 || _anyRelatedUninstallers);
            buttonNext.Enabled = PageNumber + 1 < tabControl1.TabCount;

            UseWaitCursor = false;

            _previousPageNumber = PageNumber;
        }
 private static List <BulkUninstallEntry> SortTaskEntryList(List <BulkUninstallEntry> taskEntries)
 {
     return(Settings.Default.AdvancedIntelligentUninstallerSorting
         ? AppUninstaller.SortIntelligently(taskEntries).ToList()
         : taskEntries.OrderBy(x => x.UninstallerEntry.DisplayName).ToList());
 }
Example #6
0
        private async Task <ExitCode> RunTest(
            ILogger logger,
            TestTarget target,
            Logs logs,
            ProcessManager processManager,
            IHardwareDeviceLoader deviceLoader,
            ISimulatorLoader simulatorLoader,
            ITunnelBore?tunnelBore,
            CancellationToken cancellationToken = default)
        {
            logger.LogInformation($"Starting test for {target.AsString()}{ (_arguments.DeviceName != null ? " targeting " + _arguments.DeviceName : null) }..");

            string mainLogFile = Path.Join(_arguments.OutputDirectory, $"run-{target}{(_arguments.DeviceName != null ? "-" + _arguments.DeviceName : null)}.log");
            ILog   mainLog     = logs.Create(mainLogFile, LogType.ExecutionLog.ToString(), true);
            int    verbosity   = GetMlaunchVerbosity(_arguments.Verbosity);

            string?deviceName = _arguments.DeviceName;

            var appBundleInformationParser = new AppBundleInformationParser(processManager);

            AppBundleInformation appBundleInfo;

            try
            {
                appBundleInfo = await appBundleInformationParser.ParseFromAppBundle(_arguments.AppPackagePath, target, mainLog, cancellationToken);
            }
            catch (Exception e)
            {
                logger.LogError($"Failed to get bundle information: {e.Message}");
                return(ExitCode.FAILED_TO_GET_BUNDLE_INFO);
            }

            if (!target.IsSimulator())
            {
                logger.LogInformation($"Installing application '{appBundleInfo.AppName}' on " + (deviceName != null ? $" on device '{deviceName}'" : target.AsString()));

                var appInstaller = new AppInstaller(processManager, deviceLoader, mainLog, verbosity);

                ProcessExecutionResult result;

                try
                {
                    (deviceName, result) = await appInstaller.InstallApp(_arguments.AppPackagePath, target, cancellationToken : cancellationToken);
                }
                catch (NoDeviceFoundException)
                {
                    logger.LogError($"Failed to find suitable device for target {target.AsString()}");
                    return(ExitCode.DEVICE_NOT_FOUND);
                }
                catch (Exception e)
                {
                    logger.LogError($"Failed to install the app bundle:{Environment.NewLine}{e}");
                    return(ExitCode.PACKAGE_INSTALLATION_FAILURE);
                }

                if (!result.Succeeded)
                {
                    // use the knowledge base class to decide if the error is known, if it is, let the user know
                    // the failure reason
                    if (_errorKnowledgeBase.IsKnownInstallIssue(mainLog, out var errorMessage))
                    {
                        logger.LogError($"Failed to install the app bundle (exit code={result.ExitCode}): {errorMessage}");
                    }
                    else
                    {
                        logger.LogError($"Failed to install the app bundle (exit code={result.ExitCode})");
                    }

                    return(ExitCode.PACKAGE_INSTALLATION_FAILURE);
                }

                logger.LogInformation($"Application '{appBundleInfo.AppName}' was installed successfully on device '{deviceName}'");
            }

            logger.LogInformation($"Starting application '{appBundleInfo.AppName}' on " + (deviceName != null ? $"device '{deviceName}'" : target.AsString()));

            var appRunner = new AppRunner(
                processManager,
                deviceLoader,
                simulatorLoader,
                new SimpleListenerFactory(tunnelBore),
                new CrashSnapshotReporterFactory(processManager),
                new CaptureLogFactory(),
                new DeviceLogCapturerFactory(processManager),
                new TestReporterFactory(processManager),
                mainLog,
                logs,
                new Helpers(),
                useXmlOutput: true); // the cli ALWAYS will get the output as xml

            try
            {
                string resultMessage;
                TestExecutingResult testResult;
                (deviceName, testResult, resultMessage) = await appRunner.RunApp(appBundleInfo,
                                                                                 target,
                                                                                 _arguments.Timeout,
                                                                                 _arguments.LaunchTimeout,
                                                                                 deviceName,
                                                                                 verbosity : verbosity,
                                                                                 xmlResultJargon : _arguments.XmlResultJargon,
                                                                                 cancellationToken : cancellationToken);

                switch (testResult)
                {
                case TestExecutingResult.Succeeded:
                    logger.LogInformation($"Application finished the test run successfully");
                    logger.LogInformation(resultMessage);

                    return(ExitCode.SUCCESS);

                case TestExecutingResult.Failed:
                    logger.LogInformation($"Application finished the test run successfully with some failed tests");
                    logger.LogInformation(resultMessage);

                    return(ExitCode.TESTS_FAILED);

                case TestExecutingResult.Crashed:

                    if (resultMessage != null)
                    {
                        logger.LogError($"Application run crashed:{Environment.NewLine}" +
                                        $"{resultMessage}{Environment.NewLine}{Environment.NewLine}" +
                                        $"Check logs for more information.");
                    }
                    else
                    {
                        logger.LogError($"Application run crashed. Check logs for more information");
                    }

                    return(ExitCode.APP_CRASH);

                case TestExecutingResult.TimedOut:
                    logger.LogWarning($"Application run timed out");

                    return(ExitCode.TIMED_OUT);

                default:

                    if (resultMessage != null)
                    {
                        logger.LogError($"Application run ended in an unexpected way: '{testResult}'{Environment.NewLine}" +
                                        $"{resultMessage}{Environment.NewLine}{Environment.NewLine}" +
                                        $"Check logs for more information.");
                    }
                    else
                    {
                        logger.LogError($"Application run ended in an unexpected way: '{testResult}'. Check logs for more information");
                    }

                    return(ExitCode.GENERAL_FAILURE);
                }
            }
            catch (NoDeviceFoundException)
            {
                logger.LogError($"Failed to find suitable device for target {target.AsString()}");
                return(ExitCode.DEVICE_NOT_FOUND);
            }
            catch (Exception e)
            {
                if (_errorKnowledgeBase.IsKnownTestIssue(mainLog, out var failureMessage))
                {
                    logger.LogError($"Application run failed:{Environment.NewLine}{failureMessage}");
                }
                else
                {
                    logger.LogError($"Application run failed:{Environment.NewLine}{e}");
                }

                return(ExitCode.APP_CRASH);
            }
            finally
            {
                if (!target.IsSimulator() && deviceName != null)
                {
                    logger.LogInformation($"Uninstalling the application '{appBundleInfo.AppName}' from device '{deviceName}'");

                    var appUninstaller  = new AppUninstaller(processManager, mainLog, verbosity);
                    var uninstallResult = await appUninstaller.UninstallApp(deviceName, appBundleInfo.BundleIdentifier, cancellationToken);

                    if (!uninstallResult.Succeeded)
                    {
                        logger.LogError($"Failed to uninstall the app bundle with exit code: {uninstallResult.ExitCode}");
                    }
                    else
                    {
                        logger.LogInformation($"Application '{appBundleInfo.AppName}' was uninstalled successfully");
                    }
                }
            }
        }
        private void buttonAccept_Click(object sender, EventArgs e)
        {
            Enabled = false;
            try
            {
                var filters = SelectedJunk.OfType <FileSystemJunk>().Select(x => x.Path.FullName).Distinct().ToArray();
                if (!AppUninstaller.CheckForRunningProcesses(filters, false, this))
                {
                    return;
                }

                if (SelectedJunk.Any(x => !(x is FileSystemJunk)))
                {
                    if (Settings.Default.BackupLeftovers == YesNoAsk.Ask)
                    {
                        switch (MessageBoxes.BackupRegistryQuestion(this))
                        {
                        case MessageBoxes.PressedButton.Yes:
                            var path = MessageBoxes.SelectFolder(
                                Localisable.JunkRemoveWindow_SelectBackupDirectoryTitle);

                            if (string.IsNullOrEmpty(path))
                            {
                                return;
                            }

                            try
                            {
                                CreateBackup(path);
                                Settings.Default.BackupLeftoversDirectory = path;
                            }
                            catch (OperationCanceledException)
                            {
                                goto case MessageBoxes.PressedButton.Yes;
                            }

                            break;

                        case MessageBoxes.PressedButton.No:
                            break;

                        default:
                            return;
                        }
                    }
                    else if (Settings.Default.BackupLeftovers == YesNoAsk.Yes)
                    {
                        while (true)
                        {
                            if (Directory.Exists(Settings.Default.BackupLeftoversDirectory))
                            {
                                try
                                {
                                    CreateBackup(Settings.Default.BackupLeftoversDirectory);
                                    break;
                                }
                                catch (OperationCanceledException)
                                {
                                }
                            }

                            Settings.Default.BackupLeftoversDirectory =
                                MessageBoxes.SelectFolder(Localisable.JunkRemoveWindow_SelectBackupDirectoryTitle);

                            if (string.IsNullOrEmpty(Settings.Default.BackupLeftoversDirectory))
                            {
                                Settings.Default.BackupLeftoversDirectory = string.Empty;
                                Settings.Default.BackupLeftovers          = YesNoAsk.Ask;
                                return;
                            }
                        }
                    }
                }

                DialogResult = DialogResult.OK;
                Close();
            }
            finally
            {
                Enabled = true;
            }
        }
Example #8
0
        private async Task <ExitCode> RunTest(TestTarget target,
                                              Logs logs,
                                              ProcessManager processManager,
                                              IHardwareDeviceLoader deviceLoader,
                                              ISimulatorLoader simulatorLoader,
                                              CancellationToken cancellationToken = default)
        {
            _log.LogInformation($"Starting test for {target.AsString()}{ (_arguments.DeviceName != null ? " targeting " + _arguments.DeviceName : null) }..");

            string mainLogFile = Path.Join(_arguments.OutputDirectory, $"run-{target}{(_arguments.DeviceName != null ? "-" + _arguments.DeviceName : null)}.log");
            ILog   mainLog     = logs.Create(mainLogFile, LogType.ExecutionLog.ToString(), true);
            int    verbosity   = _arguments.Verbosity.ToInt();

            string deviceName = _arguments.DeviceName;

            var appBundleInformationParser = new AppBundleInformationParser(processManager);

            AppBundleInformation appBundleInfo;

            try
            {
                appBundleInfo = await appBundleInformationParser.ParseFromAppBundle(_arguments.AppPackagePath, target, mainLog, cancellationToken);
            }
            catch (Exception e)
            {
                _log.LogError($"Failed to get bundle information: {e.Message}");
                return(ExitCode.FAILED_TO_GET_BUNDLE_INFO);
            }

            if (!target.IsSimulator())
            {
                _log.LogInformation($"Installing application '{appBundleInfo.AppName}' on " + (deviceName != null ? " on device '{deviceName}'" : target.AsString()));

                var appInstaller = new AppInstaller(processManager, deviceLoader, mainLog, verbosity);

                ProcessExecutionResult result;

                try
                {
                    (deviceName, result) = await appInstaller.InstallApp(_arguments.AppPackagePath, target, cancellationToken : cancellationToken);
                }
                catch (NoDeviceFoundException)
                {
                    _log.LogError($"Failed to find suitable device for target {target.AsString()}");
                    return(ExitCode.DEVICE_NOT_FOUND);
                }
                catch (Exception e)
                {
                    _log.LogError($"Failed to install the app bundle:{Environment.NewLine}{e}");
                    return(ExitCode.PACKAGE_INSTALLATION_FAILURE);
                }

                if (!result.Succeeded)
                {
                    _log.LogError($"Failed to install the app bundle (exit code={result.ExitCode})");
                    return(ExitCode.PACKAGE_INSTALLATION_FAILURE);
                }

                _log.LogInformation($"Application '{appBundleInfo.AppName}' was installed successfully on device '{deviceName}'");
            }

            _log.LogInformation($"Starting application '{appBundleInfo.AppName}' on " + (deviceName != null ? " on device '{deviceName}'" : target.AsString()));

            int exitCode;

            try
            {
                var appRunner = new AppRunner(
                    processManager,
                    deviceLoader,
                    simulatorLoader,
                    new SimpleListenerFactory(),
                    new CrashSnapshotReporterFactory(processManager),
                    new CaptureLogFactory(),
                    new DeviceLogCapturerFactory(processManager),
                    new TestReporterFactory(processManager),
                    mainLog,
                    logs,
                    new Helpers());

                (deviceName, exitCode) = await appRunner.RunApp(appBundleInfo,
                                                                target,
                                                                _arguments.Timeout,
                                                                _arguments.LaunchTimeout,
                                                                deviceName,
                                                                verbosity : verbosity,
                                                                xmlResultJargon : XmlResultJargon.xUnit);

                if (exitCode != 0)
                {
                    _log.LogError($"App bundle run failed with exit code {exitCode}. Check logs for more information");
                }
                else
                {
                    _log.LogInformation("Application finished the run successfully");
                }

                return(0);
            }
            catch (NoDeviceFoundException)
            {
                _log.LogError($"Failed to find suitable device for target {target.AsString()}");
                return(ExitCode.DEVICE_NOT_FOUND);
            }
            catch (Exception e)
            {
                _log.LogError($"Application run failed:{Environment.NewLine}{e}");
                return(ExitCode.APP_CRASH);
            }
            finally
            {
                if (!target.IsSimulator())
                {
                    _log.LogInformation($"Uninstalling the application '{appBundleInfo.AppName}' from device '{deviceName}'");

                    var appUninstaller  = new AppUninstaller(processManager, mainLog, verbosity);
                    var uninstallResult = await appUninstaller.UninstallApp(deviceName, appBundleInfo.BundleIdentifier, cancellationToken);

                    if (!uninstallResult.Succeeded)
                    {
                        _log.LogError($"Failed to uninstall the app bundle with exit code: {uninstallResult.ExitCode}");
                    }
                    else
                    {
                        _log.LogInformation($"Application '{appBundleInfo.AppName}' was uninstalled successfully");
                    }
                }
            }
        }
Example #9
0
        private async Task <ExitCode> RunTest(
            ILogger logger,
            TestTargetOs target,
            Logs logs,
            MLaunchProcessManager processManager,
            IHardwareDeviceLoader deviceLoader,
            ISimulatorLoader simulatorLoader,
            ITunnelBore?tunnelBore,
            CancellationToken cancellationToken = default)
        {
            var isLldbEnabled = IsLldbEnabled();

            if (isLldbEnabled && !_arguments.EnableLldb)
            {
                // the file is present, but the user did not set it, warn him about it
                logger.LogWarning("Lldb will be used since '~/.mtouch-launch-with-lldb' was found in the system but it was not created by xharness.");
            }
            else if (_arguments.EnableLldb)
            {
                if (!File.Exists(s_mlaunchLldbConfigFile))
                {
                    // create empty file
                    File.WriteAllText(s_mlaunchLldbConfigFile, string.Empty);
                    _createdLldbFile = true;
                }
            }

            logger.LogInformation($"Starting test for {target.AsString()}{ (_arguments.DeviceName != null ? " targeting " + _arguments.DeviceName : null) }..");

            string mainLogFile = Path.Join(_arguments.OutputDirectory, $"run-{target.AsString()}{(_arguments.DeviceName != null ? "-" + _arguments.DeviceName : null)}.log");

            IFileBackedLog mainLog = Log.CreateReadableAggregatedLog(
                logs.Create(mainLogFile, LogType.ExecutionLog.ToString(), true),
                new CallbackLog(message => logger.LogDebug(message.Trim()))
            {
                Timestamp = false
            });

            int verbosity = GetMlaunchVerbosity(_arguments.Verbosity);

            string?deviceName = _arguments.DeviceName;

            var appBundleInformationParser = new AppBundleInformationParser(processManager);

            AppBundleInformation appBundleInfo;

            try
            {
                appBundleInfo = await appBundleInformationParser.ParseFromAppBundle(_arguments.AppPackagePath, target.Platform, mainLog, cancellationToken);
            }
            catch (Exception e)
            {
                logger.LogError($"Failed to get bundle information: {e.Message}");
                return(ExitCode.FAILED_TO_GET_BUNDLE_INFO);
            }

            if (!target.Platform.IsSimulator())
            {
                logger.LogInformation($"Installing application '{appBundleInfo.AppName}' on " + (deviceName != null ? $" on device '{deviceName}'" : target.AsString()));

                var appInstaller = new AppInstaller(processManager, deviceLoader, mainLog, verbosity);

                ProcessExecutionResult result;

                try
                {
                    (deviceName, result) = await appInstaller.InstallApp(appBundleInfo, target, cancellationToken : cancellationToken);
                }
                catch (NoDeviceFoundException)
                {
                    logger.LogError($"Failed to find suitable device for target {target.AsString()}" + Environment.NewLine +
                                    "Please make sure the device is connected and unlocked.");
                    return(ExitCode.DEVICE_NOT_FOUND);
                }
                catch (Exception e)
                {
                    logger.LogError($"Failed to install the app bundle:{Environment.NewLine}{e}");
                    return(ExitCode.PACKAGE_INSTALLATION_FAILURE);
                }

                if (!result.Succeeded)
                {
                    // use the knowledge base class to decide if the error is known, if it is, let the user know
                    // the failure reason
                    if (_errorKnowledgeBase.IsKnownInstallIssue(mainLog, out var errorMessage))
                    {
                        var msg = $"Failed to install the app bundle (exit code={result.ExitCode}): {errorMessage.Value.HumanMessage}.";
                        if (errorMessage.Value.IssueLink != null)
                        {
                            msg += $" Find more information at {errorMessage.Value.IssueLink}";
                        }

                        logger.LogError(msg);
                    }
                    else
                    {
                        logger.LogError($"Failed to install the app bundle (exit code={result.ExitCode})");
                    }

                    return(ExitCode.PACKAGE_INSTALLATION_FAILURE);
                }

                logger.LogInformation($"Application '{appBundleInfo.AppName}' was installed successfully on device '{deviceName}'");
            }

            logger.LogInformation($"Starting application '{appBundleInfo.AppName}' on " + (deviceName != null ? $"device '{deviceName}'" : target.AsString()));

            // only add the extra callback if we do know that the feature was indeed enabled
            Action <string>?logCallback = isLldbEnabled ? (l) => NotifyUserLldbCommand(logger, l) : (Action <string>?)null;

            var appRunner = new AppRunner(
                processManager,
                deviceLoader,
                simulatorLoader,
                new SimpleListenerFactory(tunnelBore),
                new CrashSnapshotReporterFactory(processManager),
                new CaptureLogFactory(),
                new DeviceLogCapturerFactory(processManager),
                new TestReporterFactory(processManager),
                new XmlResultParser(),
                mainLog,
                logs,
                new Helpers(),
                logCallback: logCallback,
                appArguments: PassThroughArguments);

            try
            {
                string resultMessage;
                TestExecutingResult testResult;
                (deviceName, testResult, resultMessage) = await appRunner.RunApp(appBundleInfo,
                                                                                 target,
                                                                                 _arguments.Timeout,
                                                                                 _arguments.LaunchTimeout,
                                                                                 deviceName,
                                                                                 verbosity : verbosity,
                                                                                 xmlResultJargon : _arguments.XmlResultJargon,
                                                                                 cancellationToken : cancellationToken,
                                                                                 skippedMethods : _arguments.SingleMethodFilters?.ToArray(),
                                                                                 skippedTestClasses : _arguments.ClassMethodFilters?.ToArray());

                switch (testResult)
                {
                case TestExecutingResult.Succeeded:
                    logger.LogInformation($"Application finished the test run successfully");
                    logger.LogInformation(resultMessage);

                    return(ExitCode.SUCCESS);

                case TestExecutingResult.Failed:
                    logger.LogInformation($"Application finished the test run successfully with some failed tests");
                    logger.LogInformation(resultMessage);

                    return(ExitCode.TESTS_FAILED);

                case TestExecutingResult.LaunchFailure:

                    if (resultMessage != null)
                    {
                        logger.LogError($"Failed to launch the application:{Environment.NewLine}" +
                                        $"{resultMessage}{Environment.NewLine}{Environment.NewLine}" +
                                        $"Check logs for more information.");
                    }
                    else
                    {
                        logger.LogError($"Failed to launch the application. Check logs for more information");
                    }

                    return(ExitCode.APP_LAUNCH_FAILURE);

                case TestExecutingResult.Crashed:

                    if (resultMessage != null)
                    {
                        logger.LogError($"Application run crashed:{Environment.NewLine}" +
                                        $"{resultMessage}{Environment.NewLine}{Environment.NewLine}" +
                                        $"Check logs for more information.");
                    }
                    else
                    {
                        logger.LogError($"Application run crashed. Check logs for more information");
                    }

                    return(ExitCode.APP_CRASH);

                case TestExecutingResult.TimedOut:
                    logger.LogWarning($"Application run timed out");

                    return(ExitCode.TIMED_OUT);

                default:

                    if (resultMessage != null)
                    {
                        logger.LogError($"Application run ended in an unexpected way: '{testResult}'{Environment.NewLine}" +
                                        $"{resultMessage}{Environment.NewLine}{Environment.NewLine}" +
                                        $"Check logs for more information.");
                    }
                    else
                    {
                        logger.LogError($"Application run ended in an unexpected way: '{testResult}'. Check logs for more information");
                    }

                    return(ExitCode.GENERAL_FAILURE);
                }
            }
            catch (NoDeviceFoundException)
            {
                logger.LogError($"Failed to find suitable device for target {target.AsString()}" +
                                (target.Platform.IsSimulator() ? Environment.NewLine + "Please make sure suitable Simulator is installed in Xcode" : string.Empty));

                return(ExitCode.DEVICE_NOT_FOUND);
            }
            catch (Exception e)
            {
                if (_errorKnowledgeBase.IsKnownTestIssue(mainLog, out var failureMessage))
                {
                    var msg = $"Application run failed:{Environment.NewLine}{failureMessage.Value.HumanMessage}.";
                    if (failureMessage.Value.IssueLink != null)
                    {
                        msg += $" Find more information at {failureMessage.Value.IssueLink}";
                    }

                    logger.LogError(msg);
                }
                else
                {
                    logger.LogError($"Application run failed:{Environment.NewLine}{e}");
                }

                return(ExitCode.APP_CRASH);
            }
            finally
            {
                mainLog.Dispose();

                if (!target.Platform.IsSimulator() && deviceName != null)
                {
                    logger.LogInformation($"Uninstalling the application '{appBundleInfo.AppName}' from device '{deviceName}'");

                    var appUninstaller  = new AppUninstaller(processManager, mainLog, verbosity);
                    var uninstallResult = await appUninstaller.UninstallApp(deviceName, appBundleInfo.BundleIdentifier, cancellationToken);

                    if (!uninstallResult.Succeeded)
                    {
                        logger.LogError($"Failed to uninstall the app bundle with exit code: {uninstallResult.ExitCode}");
                    }
                    else
                    {
                        logger.LogInformation($"Application '{appBundleInfo.AppName}' was uninstalled successfully");
                    }
                }

                if (_createdLldbFile) // clean after the setting
                {
                    File.Delete(s_mlaunchLldbConfigFile);
                }
            }
        }