public async Task LoadDevices(ILog log, bool includeLocked = false, bool forceRefresh = false, bool listExtraData = false) { await _semaphore.WaitAsync(); if (_loaded) { if (!forceRefresh) { _semaphore.Release(); return; } _supportedRuntimes.Reset(); _supportedDeviceTypes.Reset(); _availableDevices.Reset(); _availableDevicePairs.Reset(); } var tmpfile = Path.GetTempFileName(); try { var arguments = new MlaunchArguments( new ListSimulatorsArgument(tmpfile), new XmlOutputFormatArgument()); var result = await _processManager.ExecuteCommandAsync(arguments, log, timeout : TimeSpan.FromSeconds(30)); if (!result.Succeeded) { // mlaunch can sometimes return 0 but hang and timeout. It still outputs returns valid content to the tmp file log.WriteLine($"mlaunch failed when listing simulators but trying to parse the results anyway"); } var fileInfo = new FileInfo(tmpfile); if (!fileInfo.Exists || fileInfo.Length == 0) { throw new Exception($"Failed to list simulators - no XML with devices found. " + $"mlaunch {(result.TimedOut ? "timed out" : "exited")} with {result.ExitCode})"); } var xmlContent = File.ReadAllText(tmpfile); log.WriteLine("Simulator listing returned:" + Environment.NewLine + xmlContent); var simulatorData = new XmlDocument(); simulatorData.LoadWithoutNetworkAccess(tmpfile); foreach (XmlNode?sim in simulatorData.SelectNodes("/MTouch/Simulator/SupportedRuntimes/SimRuntime")) { if (sim == null) { continue; } _supportedRuntimes.Add(new SimRuntime( name: sim.SelectSingleNode("Name").InnerText, identifier: sim.SelectSingleNode("Identifier").InnerText, version: long.Parse(sim.SelectSingleNode("Version").InnerText))); } foreach (XmlNode?sim in simulatorData.SelectNodes("/MTouch/Simulator/SupportedDeviceTypes/SimDeviceType")) { if (sim == null) { continue; } _supportedDeviceTypes.Add(new SimDeviceType( name: sim.SelectSingleNode("Name").InnerText, identifier: sim.SelectSingleNode("Identifier").InnerText, productFamilyId: sim.SelectSingleNode("ProductFamilyId").InnerText, minRuntimeVersion: long.Parse(sim.SelectSingleNode("MinRuntimeVersion").InnerText), maxRuntimeVersion: long.Parse(sim.SelectSingleNode("MaxRuntimeVersion").InnerText), supports64Bits: bool.Parse(sim.SelectSingleNode("Supports64Bits").InnerText))); } foreach (XmlNode?sim in simulatorData.SelectNodes("/MTouch/Simulator/AvailableDevices/SimDevice")) { if (sim == null) { continue; } _availableDevices.Add(new SimulatorDevice(_processManager, new TCCDatabase(_processManager)) { Name = sim.Attributes["Name"].Value, UDID = sim.Attributes["UDID"].Value, SimRuntime = sim.SelectSingleNode("SimRuntime").InnerText, SimDeviceType = sim.SelectSingleNode("SimDeviceType").InnerText, DataPath = sim.SelectSingleNode("DataPath").InnerText, LogPath = sim.SelectSingleNode("LogPath").InnerText, }); } var sim_device_pairs = simulatorData. SelectNodes("/MTouch/Simulator/AvailableDevicePairs/SimDevicePair"). Cast <XmlNode>(). // There can be duplicates, so remove those. Distinct(new SimulatorXmlNodeComparer()); foreach (XmlNode sim in sim_device_pairs) { _availableDevicePairs.Add(new SimDevicePair( uDID: sim.Attributes["UDID"].Value, companion: sim.SelectSingleNode("Companion").InnerText, gizmo: sim.SelectSingleNode("Gizmo").InnerText)); } } finally { _loaded = true; _supportedRuntimes.SetCompleted(); _supportedDeviceTypes.SetCompleted(); _availableDevices.SetCompleted(); _availableDevicePairs.SetCompleted(); File.Delete(tmpfile); _semaphore.Release(); } }
public async Task LoadDevices(ILog log, bool includeLocked = false, bool forceRefresh = false, bool listExtraData = false) { if (loaded) { if (!forceRefresh) { return; } connectedDevices.Reset(); } loaded = true; var tmpfile = Path.GetTempFileName(); try { using (var process = new Process()) { var arguments = new MlaunchArguments( new ListDevicesArgument(tmpfile), new XmlOutputFormatArgument()); if (listExtraData) { arguments.Add(new ListExtraDataArgument()); } var task = processManager.RunAsync(process, arguments, log, timeout: TimeSpan.FromSeconds(120)); log.WriteLine("Launching {0} {1}", process.StartInfo.FileName, process.StartInfo.Arguments); var result = await task; if (!result.Succeeded) { throw new Exception("Failed to list devices."); } log.WriteLine("Result:"); log.WriteLine(File.ReadAllText(tmpfile)); log.Flush(); var doc = new XmlDocument(); doc.LoadWithoutNetworkAccess(tmpfile); foreach (XmlNode dev in doc.SelectNodes("/MTouch/Device")) { var d = GetDevice(dev); if (d == null) { continue; } if (!includeLocked && d.IsLocked) { log.WriteLine($"Skipping device {d.Name} ({d.DeviceIdentifier}) because it's locked."); continue; } if (d.IsUsableForDebugging.HasValue && !d.IsUsableForDebugging.Value) { log.WriteLine($"Skipping device {d.Name} ({d.DeviceIdentifier}) because it's not usable for debugging."); continue; } connectedDevices.Add(d); } } } finally { connectedDevices.SetCompleted(); File.Delete(tmpfile); log.Flush(); } }
public async Task LoadAsync(ILog log, bool extra_data = false, bool removed_locked = false, bool force = false) { if (loaded) { if (!force) { return; } connected_devices.Reset(); } loaded = true; await Task.Run(async() => { var tmpfile = Path.GetTempFileName(); try { using (var process = new Process()) { process.StartInfo.FileName = Harness.MlaunchPath; var arguments = new MlaunchArguments( (MlaunchArgumentType.SdkRoot, Harness.XcodeRoot), (MlaunchArgumentType.ListDev, tmpfile), (MlaunchArgumentType.OutputFormat, "xml") ); if (extra_data) { arguments.Add(MlaunchArgumentType.ListExtraData); } log.WriteLine("Launching {0} {1}", process.StartInfo.FileName, process.StartInfo.Arguments); var rv = await ProcessManager.RunAsync(process, arguments, log, timeout: TimeSpan.FromSeconds(120)); if (!rv.Succeeded) { throw new Exception("Failed to list devices."); } log.WriteLine("Result:"); log.WriteLine(File.ReadAllText(tmpfile)); log.Flush(); var doc = new XmlDocument(); doc.LoadWithoutNetworkAccess(tmpfile); foreach (XmlNode dev in doc.SelectNodes("/MTouch/Device")) { var usable = dev.SelectSingleNode("IsUsableForDebugging")?.InnerText; Device d = new Device { DeviceIdentifier = dev.SelectSingleNode("DeviceIdentifier")?.InnerText, DeviceClass = dev.SelectSingleNode("DeviceClass")?.InnerText, CompanionIdentifier = dev.SelectSingleNode("CompanionIdentifier")?.InnerText, Name = dev.SelectSingleNode("Name")?.InnerText, BuildVersion = dev.SelectSingleNode("BuildVersion")?.InnerText, ProductVersion = dev.SelectSingleNode("ProductVersion")?.InnerText, ProductType = dev.SelectSingleNode("ProductType")?.InnerText, InterfaceType = dev.SelectSingleNode("InterfaceType")?.InnerText, IsUsableForDebugging = usable == null ? (bool?)null : ((bool?)(usable == "True")), }; bool.TryParse(dev.SelectSingleNode("IsLocked")?.InnerText, out var locked); d.IsLocked = locked; if (removed_locked && d.IsLocked) { log.WriteLine($"Skipping device {d.Name} ({d.DeviceIdentifier}) because it's locked."); continue; } if (d.IsUsableForDebugging.HasValue && !d.IsUsableForDebugging.Value) { log.WriteLine($"Skipping device {d.Name} ({d.DeviceIdentifier}) because it's not usable for debugging."); continue; } connected_devices.Add(d); } } } finally { connected_devices.SetCompleted(); File.Delete(tmpfile); log.Flush(); } }); }