/// <summary> /// Main application entry point. /// </summary> /// <param name="args"> /// Arguments. /// </param> public static void Main(string[] args) { #if __DEBUGGER_WAIT__ bool loop = true; while (loop) { Thread.Sleep(1); } #endif // Emulicious Debug port. var port = int.Parse(args[0]); // Path to write communication logs to. var debugPath = args[1].Trim('"'); // Mapping file path. var mappingPath = args[2].Trim('"'); // Path to the project mapping file. var projectMapping = Path.Combine(mappingPath, "ProjectMapping.json"); var settings = PassthroughSettings.LoadFromFile(projectMapping); // Start capturing STD In/Out so we dont lose any var adapter = new PassthroughAdapter(Console.OpenStandardInput(), Console.OpenStandardOutput(), settings, port); adapter.Run(); adapter.Dispose(); }
/// <summary> /// Configure the modifiers to run. /// </summary> /// <returns> /// The list of modifiers to execute. /// </returns> private IList <IJsonModifier> ConfigureModifiers(PassthroughSettings settings, StreamDirection direction) { // Configure the modifiers; var modifiers = new List <IJsonModifier>(); if (settings.UseLegacySourceFolders) { if (direction == StreamDirection.ToClient) { modifiers.Add(new LegacySourcePathRenameModifier(settings.GetLegacySourceFolders(), DebugLog)); } else { // Flip the modifier for host mapping. modifiers.Add(new LegacySourcePathRenameModifier(settings.GetLegacySourceFolders().ToDictionary((pair) => pair.Value, (pair) => pair.Key), DebugLog)); } } if (settings.UseLegacyBreakpointFix) { modifiers.Add(new LegacyBreakpointModifier()); } return(modifiers); }
/// <inheritdoc /> public override async Task LaunchAsync(DebugLaunchOptions launchOptions) { var props = ConfiguredProject.Services.ProjectPropertiesProvider.GetCommonProperties(); var debugDir = await props.GetEvaluatedPropertyValueAsync("OutDir"); await TaskFactory.SwitchToMainThreadAsync(); // Collect the source folders to map. var properties = await DebuggerProperties.GetEmuliciousDebuggerPropertiesAsync(); var sourcePaths = (IReadOnlyCollection <string>) await properties.EmuliciousSourcePaths.GetValueAsync(); // Get the projects for folder mapping. var projectPairs = new Dictionary <string, string>(); if (sourcePaths == null || sourcePaths.Count == 0) { // Bind every project. await RecurseProjectsAsync(VisualStudio.Solution.Projects, projectPairs); } else { var index = 0; foreach (var path in sourcePaths.Distinct()) { projectPairs.Add(string.Format("SourcePath{0}", index), Path.GetFullPath(path).TrimEnd('/', '\\')); ++index; } } if (EmuliciousLegacySourceFolders) { // Create junctions to the source files. CreateProjectJunctions(projectPairs, debugDir); } var executable = (string)await properties.EmuliciousDebuggerExecutable.GetValueAsync(); var romName = (string)await properties.EmuliciousLaunchRom.GetValueAsync(); var attach = (bool)await properties.EmuliciousDebuggerDebuggerAttach.GetValueAsync(); var stopOnEntry = (bool)await properties.EmuliciousDebuggerDebuggerStopOnEntry.GetValueAsync(); var debuggerPort = (int)await properties.EmuliciousDebuggerPort.GetValueAsync(); var startDelay = (int)await properties.EmuliciousDebuggerStartDelay.GetValueAsync(); var debugPath = (string)await properties.EmuliciousDebugLogPath.GetValueAsync(); var useLegacySrc = (bool)await properties.EmuliciousLegacySourceFolders.GetValueAsync(); var useLegacyBreakPointFix = (bool)await properties.EmuliciousLegacyBreakpointFix.GetValueAsync(); var useRemoteDebugArg = (bool)await properties.EmuliciousRemoteDebugArgument.GetValueAsync(); // Cache properties used by the launch adapter. EmuliciousExecutable = executable; EmuliciousPort = debuggerPort; EmuliciousAttach = attach; EmuliciousLaunchDelay = startDelay; EmuliciousDebugFolder = debugPath; EmuliciousMappingPath = debugDir; EmuliciousRemoteDebugArgument = useRemoteDebugArg; EmuliciousLegacySourceFolders = useLegacySrc; EmuliciousLegacyBreakpointFix = useLegacyBreakPointFix; // Create the PassthroughAdapter settings file. var mapping = new PassthroughSettings(EmuliciousLegacySourceFolders, EmuliciousLegacyBreakpointFix, projectPairs.Values, EmuliciousMappingPath, EmuliciousDebugFolder); mapping.SaveToFile(Path.Combine(debugDir, "ProjectMapping.json")); /* * File.WriteAllLines(Path.Combine(EmuliciousMappingPath, "LaunchProps.log"), * new [] * { * EmuliciousExecutable.ToString(), * EmuliciousPort.ToString(), * EmuliciousAttach.ToString(), * EmuliciousLaunchDelay.ToString(), * EmuliciousDebugFolder.ToString(), * EmuliciousMappingPath.ToString(), * EmuliciousPackage.DebugAdapterPath.ToString() * }); */ // Generate the launch.json file for emulicious. var jsonFile = Path.Combine(debugDir, "launch.json"); var launchSettings = new LaunchSettings((attach) ? LaunchSettings.RequestMode.Attach : LaunchSettings.RequestMode.Launch, debuggerPort, romName, stopOnEntry, projectPairs.Values); launchSettings.WriteToFile(jsonFile); Task.WaitAll(); // Launch the debug host adapter with our JSON file. var launchArgs = "/EngineGuid:{BE99C8E2-969A-450C-8FAB-73BECCC53DF4} " + string.Format("/LaunchJson:\"{0}\"", jsonFile); VisualStudio.ExecuteCommand("DebugAdapterHost.Launch", launchArgs); }
/// <summary> /// Default constructor. /// </summary> /// <param name="inStream"> /// Input stream. /// </param> /// <param name="outStream"> /// Output stream. /// </param> /// <param name="settings"> /// The passthrough project settings. /// </param> /// <param name="port"> /// Emulicious Debug port. /// </param> public PassthroughAdapter(Stream inStream, Stream outStream, PassthroughSettings settings, int port = 58870) { var debugPath = settings.DevelopmentPath; DebugLog = null; if (Directory.Exists(debugPath)) { var debugFile = Path.Combine(debugPath, "Debug.log"); DebugLog = new StreamWriter(File.Create(debugFile)) { AutoFlush = true }; } try { HostIn = inStream; HostOut = outStream; AdapterClient = new TcpClient() { NoDelay = true }; AdapterClient.Connect(IPAddress.Loopback, port); if (AdapterClient.Connected) { ClientIn = AdapterClient.GetStream(); ClientOut = AdapterClient.GetStream(); ToClientStream = new PathRenameStream(ClientIn, StreamDirection.ToClient, ConfigureModifiers(settings, StreamDirection.ToClient)) { DebugStream = DebugLog }; ToHostStream = new PathRenameStream(HostOut, StreamDirection.ToHost, ConfigureModifiers(settings, StreamDirection.ToHost)) { DebugStream = DebugLog }; } if (DebugLog != null) { if (AdapterClient.Connected) { DebugLog.WriteLine("*** Connected ***"); } else { DebugLog.WriteLine("*** Not Connected ***"); } } } catch (Exception err) { if (DebugLog != null) { DebugLog.Write("*** EXECPTION ***\n" + err); } } }