//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// #region IDebugPortSupplier2 Members //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public int AddPort(IDebugPortRequest2 pRequest, out IDebugPort2 ppPort) { // // Attempt to find a port matching the requested name, refreshes and iterates updated ports via EnumPorts. // LoggingUtils.PrintFunction(); try { string requestPortName; LoggingUtils.RequireOk(CanAddPort()); LoggingUtils.RequireOk(pRequest.GetPortName(out requestPortName)); ppPort = null; foreach (KeyValuePair <Guid, IDebugPort2> keyPair in m_registeredPorts) { string portName; IDebugPort2 registeredPort = keyPair.Value; LoggingUtils.RequireOk(registeredPort.GetPortName(out portName)); if (portName.Equals(requestPortName)) { ppPort = registeredPort; break; } } if (ppPort == null) { Guid portId; ppPort = CreatePort(pRequest); LoggingUtils.RequireOk(ppPort.GetPortId(out portId)); m_registeredPorts.Add(portId, ppPort); } return(Constants.S_OK); } catch (Exception e) { LoggingUtils.HandleException(e); ppPort = null; return(Constants.E_FAIL); } }
/// <summary> /// Remove the given port. /// </summary> public int RemovePort(IDebugPort2 pPort) { DLog.Debug(DContext.VSDebuggerComCall, "DebugPortSupplier.RemovePort"); string name; if (!ErrorHandler.Succeeded(pPort.GetPortName(out name))) { return(VSConstants.S_FALSE); } return(ports.Remove(name) ? VSConstants.S_OK : VSConstants.S_FALSE); }
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// #region IDebugPortSupplier2 Members //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public int AddPort(IDebugPortRequest2 pRequest, out IDebugPort2 ppPort) { // // Attempt to find a port matching the requested name, otherwise one is created. // LoggingUtils.PrintFunction(); try { string requestPortName; LoggingUtils.RequireOk(CanAddPort()); LoggingUtils.RequireOk(pRequest.GetPortName(out requestPortName)); if (string.IsNullOrWhiteSpace(requestPortName)) { throw new InvalidOperationException("Invalid/empty port name"); } ppPort = null; foreach (KeyValuePair <Guid, IDebugPort2> keyPair in m_registeredPorts) { string portName; IDebugPort2 registeredPort = keyPair.Value; LoggingUtils.RequireOk(registeredPort.GetPortName(out portName)); if (portName.Equals(requestPortName)) { ppPort = registeredPort; break; } } if (ppPort == null) { // // Create and track a new port for this request. // Guid portId; LoggingUtils.RequireOk(CreatePort(pRequest, out ppPort)); LoggingUtils.RequireOk(ppPort.GetPortId(out portId)); m_registeredPorts.Add(portId, ppPort); } return(Constants.S_OK); } catch (Exception e) { LoggingUtils.HandleException(e); ppPort = null; return(Constants.E_FAIL); } }
// Launches a process by means of the debug engine. // Normally, Visual Studio launches a program using the IDebugPortEx2::LaunchSuspended method and then attaches the debugger // to the suspended program. However, there are circumstances in which the debug engine may need to launch a program // (for example, if the debug engine is part of an interpreter and the program being debugged is an interpreted language), // in which case Visual Studio uses the IDebugEngineLaunch2::LaunchSuspended method // The IDebugEngineLaunch2::ResumeProcess method is called to start the process after the process has been successfully launched in a suspended state. int IDebugEngineLaunch2.LaunchSuspended(string pszServer, IDebugPort2 port, string exe, string args, string dir, string env, string options, enum_LAUNCH_FLAGS launchFlags, uint hStdInput, uint hStdOutput, uint hStdError, IDebugEventCallback2 ad7Callback, out IDebugProcess2 process) { //Debug.Assert(Worker.MainThreadId == Worker.CurrentThreadId); //Debug.Assert(m_pollThread == null); Debug.Assert(m_engineCallback == null); Debug.Assert(debuggedProcess == null); Debug.Assert(m_ad7ProgramId == Guid.Empty); process = null; try { //string commandLine = EngineUtils.BuildCommandLine(exe, args); //ProcessLaunchInfo processLaunchInfo = new ProcessLaunchInfo(exe, commandLine, dir, env, options, (uint)launchFlags, hStdInput, hStdOutput, hStdError); // We are being asked to debug a process when we currently aren't debugging anything //m_pollThread = new WorkerThread(); string portname; port.GetPortName(out portname); m_engineCallback = new EngineCallback(this, ad7Callback); XmlDocument doc = new XmlDocument(); doc.LoadXml(options); XmlElement root = (XmlElement)doc.ChildNodes[0]; string ipaddress = root.GetAttribute("targetaddress"); int ipport = Int32.Parse(root.GetAttribute("port")); int connectiontries = Int32.Parse(root.GetAttribute("connectiontries")); int connectiondelay = Int32.Parse(root.GetAttribute("connectiondelay")); bool autoruninterpreter = Boolean.Parse(root.GetAttribute("autoruninterpreter")); bool suspendonstartup = Boolean.Parse(root.GetAttribute("suspendonstartup")); List <SquirrelDebugFileContext> ctxs = new List <SquirrelDebugFileContext>(); foreach (XmlElement e in doc.GetElementsByTagName("context")) { string rootpath = e.GetAttribute("rootpath"); string pathfixup = e.GetAttribute("pathfixup"); SquirrelDebugFileContext sdfc = new SquirrelDebugFileContext(rootpath, pathfixup); ctxs.Add(sdfc); } // Complete the win32 attach on the poll thread //THIS IS A MASSIVE HACK //the 'options' parameter is formatted this way "targetaddress,port,autorunintepreter,suspendonstartup,projectfolder,pathfixup" //I should find a better way to pass this params //fix working dir) dir = dir.Replace('/', '\\'); Process proc = null; if (autoruninterpreter) { proc = new Process(); proc.EnableRaisingEvents = false; proc.StartInfo.UseShellExecute = false; baseDir = proc.StartInfo.WorkingDirectory = dir; proc.StartInfo.FileName = exe; proc.StartInfo.Arguments = args; proc.StartInfo.RedirectStandardOutput = false; proc.StartInfo.RedirectStandardError = false; proc.Start(); } AD_PROCESS_ID adProcessId = new AD_PROCESS_ID(); if (proc != null) { adProcessId.ProcessIdType = (uint)enum_AD_PROCESS_ID.AD_PROCESS_ID_SYSTEM; adProcessId.dwProcessId = (uint)proc.Id; } else { adProcessId.ProcessIdType = (uint)enum_AD_PROCESS_ID.AD_PROCESS_ID_GUID; adProcessId.guidProcessId = Guid.NewGuid(); } EngineUtils.RequireOk(port.GetProcess(adProcessId, out process)); debuggedProcess = (SquirrelProcess)process; debuggedProcess.Engine = this; debuggedProcess.Process = proc; debuggedProcess.Name = proc != null? proc.StartInfo.FileName : "remoteprocess"; debuggedProcess.EngineCallback = m_engineCallback; debuggedProcess.IpAddress = ipaddress; debuggedProcess.IpPort = ipport; debuggedProcess.SuspendOnStartup = suspendonstartup; debuggedProcess.FileContexts = ctxs.ToArray(); //debuggedProcess.ConnectionTries = connectiontries; //debuggedProcess.ConnectionDelay = connectiondelay; //debuggedProcess.PathFixup = pathfixup; //debuggedProcess.ProjectFolder = projectfolder; /*DebuggedThread thread = new DebuggedThread(1); * DebuggedModule module = new DebuggedModule("the module"); * * m_engineCallback.OnModuleLoad(module); * m_engineCallback.OnSymbolSearch(module, "nothing", 0); * m_engineCallback.OnThreadStart(thread); * m_engineCallback.OnLoadComplete(thread);*/ return(EngineConstants.S_OK); } catch (ComponentException e) { return(e.HRESULT); } catch (Exception e) { return(EngineUtils.UnexpectedException(e)); } }
/// <summary> /// Remove the given port. /// </summary> public int RemovePort(IDebugPort2 pPort) { DLog.Debug(DContext.VSDebuggerComCall, "DebugPortSupplier.RemovePort"); string name; if (!ErrorHandler.Succeeded(pPort.GetPortName(out name))) return VSConstants.S_FALSE; return ports.Remove(name) ? VSConstants.S_OK : VSConstants.S_FALSE; }