async Task InitializeSimulatorAsync()

in ClientIntegrations/Xamarin.Workbooks.Client.iOS/iOSAgentProcess.cs [111:262]


        async Task InitializeSimulatorAsync (
            IMessageService messageService,
            CancellationToken cancellationToken)
        {
            using (var simulatorKey = RegistryKey.OpenBaseKey (RegistryHive.LocalMachine, RegistryView.Registry32)
                .OpenSubKey (@"Software\Xamarin\Simulator\")) {
                simulatorExePath = simulatorKey?.GetValue ("Path") as string;
                simulatorSupportsExtraArgs =
                    Version.TryParse (
                        simulatorKey?.GetValue ("Version") as string,
                        out var version) &&
                    version >= new Version (1, 0, 2);
            }

            if (String.IsNullOrEmpty (simulatorExePath))
                throw new UserPresentableException (Catalog.GetString (
                    "The Xamarin Remote iOS Simulator is not installed."));

            string remoteHomeDir = null;
            foreach (var knownServer in GetXvsMacBuildHosts ().OrderByDescending (s => s.IsDefault)) {
                Log.Info (TAG, $"Trying known server {knownServer.BuildServer}");
                var ssh = new SshCommands (knownServer.Ip, knownServer.Username);
                try {
                    remoteHomeDir = await ssh.GetHomeDirectoryAsync ();
                    if (!String.IsNullOrEmpty (remoteHomeDir)) {
                        Log.Info (
                            TAG,
                            "Connected to Mac Build Host " +
                            $"{knownServer.BuildServer} at {ssh.Address}.");
                        sshCommands = ssh;
                        break;
                    }
                } catch (Exception e) {
                    Log.Error (TAG, "Could not connect to Mac build host", e);
                }
            }

            if (sshCommands == null)
                throw new UserPresentableException (
                    Catalog.GetString ("Unable to connect to the Mac build host."),
                    Catalog.GetString ("Confirm and test setup in Visual Studio."));

            const string monoPath =
                "/Library/Frameworks/Mono.framework/Versions/Current/bin/mono64";

            macTempPath = $"{remoteHomeDir}/Library/Caches/com.xamarin.Inspector/remote";

            var makeTempResult = await sshCommands.ExecuteCommandAsync ($"mkdir -p {macTempPath}");
            if (makeTempResult.ExitStatus != 0) {
                Log.Error (TAG, makeTempResult.Error);
                throw new UserPresentableException (Catalog.GetString ("Could not create temporary path on the Mac build host."));
            }

            var depCheckResult = await sshCommands.ExecuteCommandAsync ($"ls \"{monoPath}\"");
            if (depCheckResult.ExitStatus != 0) {
                Log.Error (TAG, depCheckResult.Error);
                throw new UserPresentableException (Catalog.GetString ("Mono must be installed on the Mac build host."));
            }

            var localSimChecker = InteractiveInstallation.Default.LocateSimChecker ();
            var simCheckerPath = $"{macTempPath}/{Path.GetFileName (localSimChecker)}";

            // This file is really small, so copying it fresh every time is OK.
            try {
                await sshCommands.CopyFileAsync (localSimChecker, simCheckerPath);
            } catch (Exception e) {
                Log.Error (TAG, "Could not copy SimChecker to Mac host.", e);
                throw new UserPresentableException (
                    e,
                    Catalog.GetString ("Could not copy files to Mac host."));
            }

            var simCheckerResult = await sshCommands.ExecuteCommandAsync ($"{monoPath} {simCheckerPath}");

            if (simCheckerResult.ExitStatus != 0 || String.IsNullOrEmpty (simCheckerResult.Result)) {
                // 100: Xcode not configured in XS or not installed at /Applications/Xcode.app
                // 105: Xcode too old
                if (simCheckerResult.ExitStatus == 100 || simCheckerResult.ExitStatus == 105) {
                    var ex = new UserPresentableException (
                        Catalog.GetString ("Required Xcode not found"),
                        Catalog.GetString (
                            $"Ensure Xcode {MTouchSdkTool.RequiredMinimumXcodeVersion} or " +
                            "later is installed and selected."));

                    messageService.PushMessage (CreateInstallAlert (
                        ex,
                        Catalog.GetString ("Install Xcode"),
                        "https://aka.ms/xamint-download-xcode"));

                    throw ex;
                }

                // 101: mlaunch (Xamarin Studio) not installed
                if (simCheckerResult.ExitStatus == 101) {
                    var ex = new UserPresentableException (
                        Catalog.GetString ("Missing Xamarin.iOS"),
                        Catalog.GetString ("Check that Xamarin is installed and up to date."));

                    messageService.PushMessage (CreateInstallAlert (
                        ex,
                        Catalog.GetString ("Install Xamarin"),
                        "https://aka.ms/xamint-install-xamarin"));

                    throw ex;
                }

                // 102: Error running mlaunch
                if (simCheckerResult.ExitStatus == 102)
                    throw new UserPresentableException (
                        Catalog.GetString (
                            "Unexpected error checking the Mac build host for compatible simulators."),
                        simCheckerResult.Error);

                // 103: Invalid mlaunch output
                if (simCheckerResult.ExitStatus == 103)
                    throw new UserPresentableException (
                        Catalog.GetString (
                            "Error checking the Mac build host for compatible simulators."),
                        Catalog.GetString (
                            "Check that your Xamarin Studio and configured Xcode " +
                            "are compatible with each other."));

                // 104: No compatible simulator device listed by mlaunch
                if (simCheckerResult.ExitStatus == 104)
                    throw new UserPresentableException (
                        Catalog.GetString (
                            "Unable to find a compatible simulator device " +
                            "on the Mac build host."),
                        Catalog.GetString (
                            "Check your Xcode installation."));

                throw new UserPresentableException (
                    Catalog.GetString (
                        "Unexpected error finding compatible simulator on Mac build host."),
                    simCheckerResult.Error);
            }

            var mtouchList = MTouchSdkTool.ReadFromXml (
                new MemoryStream (Encoding.UTF8.GetBytes (simCheckerResult.Result)));

            deviceUdid = MTouchSdkTool
                .GetCompatibleDevices (mtouchList)
                .FirstOrDefault ()
                ?.UDID;

            if (deviceUdid == null)
                throw new UserPresentableException (
                    Catalog.GetString (
                        "Unexpected error communicating with the Mac build host."),
                    Catalog.GetString (
                        "Check your Xcode, Xamarin, and Visual Studio configurations."));
        }