// Obtains information about programs running, filtered in a variety of ways. int IDebugProgramProvider2.GetProviderProcessData(enum_PROVIDER_FLAGS Flags, IDebugDefaultPort2 port, AD_PROCESS_ID ProcessId, CONST_GUID_ARRAY EngineFilter, PROVIDER_PROCESS_DATA[] processArray) { processArray[0] = new PROVIDER_PROCESS_DATA(); if (Flags.HasFlag(enum_PROVIDER_FLAGS.PFLAG_GET_PROGRAM_NODES)) { // The debugger is asking the engine to return the program nodes it can debug. The // sample engine claims that it can debug all processes, and returns exsactly one // program node for each process. A full-featured debugger may wish to examine the // target process and determine if it understands how to debug it. var node = (IDebugProgramNode2)(new AD7ProgramNode(ProcessId.guidProcessId)); IntPtr[] programNodes = { Marshal.GetComInterfaceForObject(node, typeof(IDebugProgramNode2)) }; IntPtr destinationArray = Marshal.AllocCoTaskMem(IntPtr.Size * programNodes.Length); Marshal.Copy(programNodes, 0, destinationArray, programNodes.Length); processArray[0].Fields = enum_PROVIDER_FIELDS.PFIELD_PROGRAM_NODES; processArray[0].ProgramNodes.Members = destinationArray; processArray[0].ProgramNodes.dwCount = (uint)programNodes.Length; return VSConstants.S_OK; } return VSConstants.S_FALSE; }
// Obtains information about programs running, filtered in a variety of ways. int IDebugProgramProvider2.GetProviderProcessData(enum_PROVIDER_FLAGS Flags, IDebugDefaultPort2 port, AD_PROCESS_ID ProcessId, CONST_GUID_ARRAY EngineFilter, PROVIDER_PROCESS_DATA[] processArray) { processArray[0] = new PROVIDER_PROCESS_DATA(); if (Flags.HasFlag(enum_PROVIDER_FLAGS.PFLAG_GET_PROGRAM_NODES)) { // The debugger is asking the engine to return the program nodes it can debug. The // sample engine claims that it can debug all processes, and returns exsactly one // program node for each process. A full-featured debugger may wish to examine the // target process and determine if it understands how to debug it. var node = (IDebugProgramNode2)(new AD7ProgramNode(ProcessId.guidProcessId)); IntPtr[] programNodes = { Marshal.GetComInterfaceForObject(node, typeof(IDebugProgramNode2)) }; IntPtr destinationArray = Marshal.AllocCoTaskMem(IntPtr.Size * programNodes.Length); Marshal.Copy(programNodes, 0, destinationArray, programNodes.Length); processArray[0].Fields = enum_PROVIDER_FIELDS.PFIELD_PROGRAM_NODES; processArray[0].ProgramNodes.Members = destinationArray; processArray[0].ProgramNodes.dwCount = (uint)programNodes.Length; return(VSConstants.S_OK); } return(VSConstants.S_FALSE); }
public int GetProviderProcessData(enum_PROVIDER_FLAGS Flags, IDebugDefaultPort2 pPort, AD_PROCESS_ID ProcessId, CONST_GUID_ARRAY EngineFilter, PROVIDER_PROCESS_DATA[] pProcess) { Log.Debug("ProgramProvider: GetProviderProcessData"); if (Flags.HasFlag(enum_PROVIDER_FLAGS.PFLAG_GET_PROGRAM_NODES)) { var process = Process.GetProcessById((int) ProcessId.dwProcessId); foreach (ProcessModule module in process.Modules) { if (module.ModuleName.StartsWith("System.Management.Automation", StringComparison.OrdinalIgnoreCase)) { var node = new ScriptProgramNode(new ScriptDebugProcess(pPort, ProcessId.dwProcessId)); var programNodes = new[] { Marshal.GetComInterfaceForObject(node, typeof(IDebugProgramNode2)) }; var destinationArray = Marshal.AllocCoTaskMem(IntPtr.Size * programNodes.Length); Marshal.Copy(programNodes, 0, destinationArray, programNodes.Length); pProcess[0].Fields = enum_PROVIDER_FIELDS.PFIELD_PROGRAM_NODES; pProcess[0].ProgramNodes.Members = destinationArray; pProcess[0].ProgramNodes.dwCount = (uint)programNodes.Length; return VSConstants.S_OK; } } } return VSConstants.S_FALSE; }
/// <summary> /// Retrieves a list of running programs from a specified process. /// </summary> /// <param name="Flags"> /// A combination of flags from the PROVIDER_FLAGS enumeration. The following flags are typical for this call: /// /// Flag Description /// PFLAG_REMOTE_PORT Caller is running on remote machine. /// PFLAG_DEBUGGEE Caller is currently being debugged (additional information about marshalling will be returned for each node). /// PFLAG_ATTACHED_TO_DEBUGGEE Caller was attached to but not launched by the debugger. /// PFLAG_GET_PROGRAM_NODES Caller is asking for a list of program nodes to be returned. /// </param> /// <param name="pPort">The port the calling process is running on.</param> /// <param name="ProcessId">An AD_PROCESS_ID structure holding the ID of the process that contains the program in question.</param> /// <param name="EngineFilter">An array of GUIDs for debug engines assigned to debug this process (these will be used to filter the programs that are actually returned based on what the supplied engines support; if no engines are specified, then all programs will be returned).</param> /// <param name="pProcess">A PROVIDER_PROCESS_DATA structure that is filled in with the requested information.</param> /// <returns>If successful, returns S_OK; otherwise, returns an error code.</returns> /// <remarks>This method is normally called by a process to obtain a list of programs running in that process. The returned information is a list of IDebugProgramNode2 objects.</remarks> public virtual int GetProviderProcessData( enum_PROVIDER_FLAGS Flags, IDebugDefaultPort2 pPort, AD_PROCESS_ID ProcessId, CONST_GUID_ARRAY EngineFilter, PROVIDER_PROCESS_DATA[] pProcess) { Logger.Debug( string.Empty ); return VSConstants.E_NOTIMPL; }
// Obtains information about programs running, filtered in a variety of ways. int IDebugProgramProvider2.GetProviderProcessData(enum_PROVIDER_FLAGS Flags, IDebugDefaultPort2 port, AD_PROCESS_ID ProcessId, CONST_GUID_ARRAY EngineFilter, PROVIDER_PROCESS_DATA[] processArray) { processArray[0] = new PROVIDER_PROCESS_DATA(); // we handle creation of the remote program provider ourselves. This is because we always load our program provider locally which keeps // attach working when developing Python Tools and running/debugging from within VS and in the experimental hive. When we are installed // we install into the GAC so these types are available to create and then remote debugging works as well. When we're running in the // experimental hive we are not in the GAC so if we're created outside of VS (e.g. in msvsmon on the local machine) then we can't get // at our program provider and debug->attach doesn't work. if (port != null && port.QueryIsLocal() == VSConstants.S_FALSE) { IDebugCoreServer3 server; if (ErrorHandler.Succeeded(port.GetServer(out server))) { IDebugCoreServer90 dbgServer = server as IDebugCoreServer90; if (dbgServer != null) { Guid g = typeof(IDebugProgramProvider2).GUID; IntPtr remoteProviderPunk; int hr = dbgServer.CreateManagedInstanceInServer(typeof(AD7ProgramProvider).FullName, typeof(AD7ProgramProvider).Assembly.FullName, 0, ref g, out remoteProviderPunk); try { if (ErrorHandler.Succeeded(hr)) { var remoteProvider = (IDebugProgramProvider2)Marshal.GetObjectForIUnknown(remoteProviderPunk); return remoteProvider.GetProviderProcessData(Flags, null, ProcessId, EngineFilter, processArray); } } finally { if (remoteProviderPunk != IntPtr.Zero) { Marshal.Release(remoteProviderPunk); } } } } } else if ((Flags & enum_PROVIDER_FLAGS.PFLAG_GET_PROGRAM_NODES) != 0 ) { // The debugger is asking the engine to return the program nodes it can debug. We check // each process if it has a python##.dll or python##_d.dll loaded and if it does // then we report the program as being a Python process. if (DebugAttach.IsPythonProcess((int)ProcessId.dwProcessId)) { IDebugProgramNode2 node = new AD7ProgramNode((int)ProcessId.dwProcessId); IntPtr[] programNodes = { Marshal.GetComInterfaceForObject(node, typeof(IDebugProgramNode2)) }; IntPtr destinationArray = Marshal.AllocCoTaskMem(IntPtr.Size * programNodes.Length); Marshal.Copy(programNodes, 0, destinationArray, programNodes.Length); processArray[0].Fields = enum_PROVIDER_FIELDS.PFIELD_PROGRAM_NODES; processArray[0].ProgramNodes.Members = destinationArray; processArray[0].ProgramNodes.dwCount = (uint)programNodes.Length; return VSConstants.S_OK; } } return VSConstants.S_FALSE; }
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// #region IDebugProgramProvider2 Members //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public int GetProviderProcessData(enum_PROVIDER_FLAGS Flags, IDebugDefaultPort2 port, AD_PROCESS_ID ProcessId, CONST_GUID_ARRAY EngineFilter, PROVIDER_PROCESS_DATA [] processArray) { // // Retrieves a list of running programs from a specified process. // LoggingUtils.PrintFunction(); try { processArray [0] = new PROVIDER_PROCESS_DATA(); if ((Flags & enum_PROVIDER_FLAGS.PFLAG_GET_PROGRAM_NODES) != 0) { // The debugger is asking the engine to return the program nodes it can debug. The // sample engine claims that it can debug all processes, and returns exactly one // program node for each process. A full-featured debugger may wish to examine the // target process and determine if it understands how to debug it. IDebugProgramNode2 node = (IDebugProgramNode2)(new DebuggeeProgram(null)); IntPtr [] programNodes = { Marshal.GetComInterfaceForObject(node, typeof(IDebugProgramNode2)) }; IntPtr destinationArray = Marshal.AllocCoTaskMem(IntPtr.Size * programNodes.Length); Marshal.Copy(programNodes, 0, destinationArray, programNodes.Length); processArray [0].Fields = enum_PROVIDER_FIELDS.PFIELD_PROGRAM_NODES; processArray [0].ProgramNodes.Members = destinationArray; processArray [0].ProgramNodes.dwCount = (uint)programNodes.Length; return(Constants.S_OK); } return(Constants.S_FALSE); } catch (Exception e) { LoggingUtils.HandleException(e); return(Constants.E_FAIL); } }
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// #region IDebugProgramProvider2 Members //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public int GetProviderProcessData (enum_PROVIDER_FLAGS Flags, IDebugDefaultPort2 port, AD_PROCESS_ID ProcessId, CONST_GUID_ARRAY EngineFilter, PROVIDER_PROCESS_DATA [] processArray) { // // Retrieves a list of running programs from a specified process. // LoggingUtils.PrintFunction (); try { processArray [0] = new PROVIDER_PROCESS_DATA (); if ((Flags & enum_PROVIDER_FLAGS.PFLAG_GET_PROGRAM_NODES) != 0) { // The debugger is asking the engine to return the program nodes it can debug. The // sample engine claims that it can debug all processes, and returns exactly one // program node for each process. A full-featured debugger may wish to examine the // target process and determine if it understands how to debug it. IDebugProgramNode2 node = (IDebugProgramNode2)(new DebuggeeProgram (null)); IntPtr [] programNodes = { Marshal.GetComInterfaceForObject (node, typeof (IDebugProgramNode2)) }; IntPtr destinationArray = Marshal.AllocCoTaskMem (IntPtr.Size * programNodes.Length); Marshal.Copy (programNodes, 0, destinationArray, programNodes.Length); processArray [0].Fields = enum_PROVIDER_FIELDS.PFIELD_PROGRAM_NODES; processArray [0].ProgramNodes.Members = destinationArray; processArray [0].ProgramNodes.dwCount = (uint)programNodes.Length; return Constants.S_OK; } return Constants.S_FALSE; } catch (Exception e) { LoggingUtils.HandleException (e); return Constants.E_FAIL; } }
// Obtains information about programs running, filtered in a variety of ways. int IDebugProgramProvider2.GetProviderProcessData(enum_PROVIDER_FLAGS Flags, IDebugDefaultPort2 port, AD_PROCESS_ID ProcessId, CONST_GUID_ARRAY EngineFilter, PROVIDER_PROCESS_DATA[] processArray) { processArray[0] = new PROVIDER_PROCESS_DATA(); // we handle creation of the remote program provider ourselves. This is because we always load our program provider locally which keeps // attach working when developing Python Tools and running/debugging from within VS and in the experimental hive. When we are installed // we install into the GAC so these types are available to create and then remote debugging works as well. When we're running in the // experimental hive we are not in the GAC so if we're created outside of VS (e.g. in msvsmon on the local machine) then we can't get // at our program provider and debug->attach doesn't work. if (port != null && port.QueryIsLocal() == VSConstants.S_FALSE) { if (ErrorHandler.Succeeded(port.GetServer(out var server))) { var dbgServer = server as IDebugCoreServer90; if (dbgServer != null) { var g = typeof(IDebugProgramProvider2).GUID; var hr = dbgServer.CreateManagedInstanceInServer(typeof(AD7ProgramProvider).FullName, typeof(AD7ProgramProvider).Assembly.FullName, 0, ref g, out var remoteProviderPunk); try { if (ErrorHandler.Succeeded(hr)) { var remoteProvider = (IDebugProgramProvider2)Marshal.GetObjectForIUnknown(remoteProviderPunk); return(remoteProvider.GetProviderProcessData(Flags, null, ProcessId, EngineFilter, processArray)); } } finally { if (remoteProviderPunk != IntPtr.Zero) { Marshal.Release(remoteProviderPunk); } } } } } else if ((Flags & enum_PROVIDER_FLAGS.PFLAG_GET_PROGRAM_NODES) != 0) { // The debugger is asking the engine to return the program nodes it can debug. We check // each process if it has a python##.dll or python##_d.dll loaded and if it does // then we report the program as being a Python process. /* * if (DebugAttach.IsPythonProcess((int)ProcessId.dwProcessId)) { * IDebugProgramNode2 node = new AD7ProgramNode((int)ProcessId.dwProcessId); * * IntPtr[] programNodes = { Marshal.GetComInterfaceForObject(node, typeof(IDebugProgramNode2)) }; * * IntPtr destinationArray = Marshal.AllocCoTaskMem(IntPtr.Size * programNodes.Length); * Marshal.Copy(programNodes, 0, destinationArray, programNodes.Length); * * processArray[0].Fields = enum_PROVIDER_FIELDS.PFIELD_PROGRAM_NODES; * processArray[0].ProgramNodes.Members = destinationArray; * processArray[0].ProgramNodes.dwCount = (uint)programNodes.Length; * * return VSConstants.S_OK; * }*/ } return(VSConstants.S_FALSE); }
int IDebugProgramProvider2.GetProviderProcessData(enum_PROVIDER_FLAGS Flags, IDebugDefaultPort2 pPort, AD_PROCESS_ID ProcessId, CONST_GUID_ARRAY EngineFilter, PROVIDER_PROCESS_DATA[] pProcess) { throw new NotImplementedException(); }
public int GetProviderProcessData(enum_PROVIDER_FLAGS Flags, IDebugDefaultPort2 pPort, AD_PROCESS_ID ProcessId, CONST_GUID_ARRAY EngineFilter, PROVIDER_PROCESS_DATA[] pProcess) { DebugHelper.TraceEnteringMethod(); return VSConstants.S_OK; }
public int GetProviderProcessData(enum_PROVIDER_FLAGS Flags, IDebugDefaultPort2 pPort, AD_PROCESS_ID ProcessId, CONST_GUID_ARRAY EngineFilter, PROVIDER_PROCESS_DATA[] pProcess) { pProcess[0] = new PROVIDER_PROCESS_DATA(); return VSConstants.S_OK; }
public int GetProviderProcessData(enum_PROVIDER_FLAGS Flags, IDebugDefaultPort2 pPort, AD_PROCESS_ID ProcessId, CONST_GUID_ARRAY EngineFilter, PROVIDER_PROCESS_DATA[] pProcess) { pProcess[0] = new PROVIDER_PROCESS_DATA(); return(VSConstants.S_OK); }