/** * Copyright (c) 20014 by Brainwy Software LTDA. All Rights Reserved. * Licensed under the terms of the Eclipse Public License (EPL). * Please see the license.txt included with this distribution for details. * Any modifications to this file must keep this entire header intact. */ package com.python.pydev.debug.actions; import java.io.File; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.core.runtime.Path; import org.eclipse.jface.action.IAction; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jface.viewers.ILabelProvider; import org.eclipse.jface.viewers.ISelection; import org.eclipse.swt.graphics.Image; import org.eclipse.ui.IWorkbenchWindow; import org.eclipse.ui.IWorkbenchWindowActionDelegate; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.dialogs.ListDialog; import org.eclipse.ui.dialogs.SelectionDialog; import org.python.pydev.core.IInterpreterInfo; import org.python.pydev.core.IInterpreterManager; import org.python.pydev.core.IPythonNature; import org.python.pydev.core.log.Log; import org.python.pydev.plugin.PydevPlugin; import org.python.pydev.plugin.nature.SystemPythonNature; import org.python.pydev.runners.SimplePythonRunner; import org.python.pydev.shared_core.structure.TreeNode; import org.python.pydev.shared_core.structure.Tuple; import org.python.pydev.shared_core.utils.IProcessInfo; import org.python.pydev.shared_core.utils.IProcessList; import org.python.pydev.shared_core.utils.PlatformUtils; import org.python.pydev.shared_ui.SharedUiPlugin; import org.python.pydev.shared_ui.UIConstants; import org.python.pydev.shared_ui.utils.UIUtils; import org.python.pydev.ui.dialogs.PyDialogHelpers; import org.python.pydev.ui.dialogs.Select1Dialog; import org.python.pydev.ui.dialogs.TreeNodeLabelProvider; import org.python.pydev.ui.pythonpathconf.AbstractInterpreterPreferencesPage; import com.python.pydev.debug.DebugPluginPrefsInitializer; import com.python.pydev.debug.remote.client_api.PydevRemoteDebuggerServer; public class AttachToProcess implements IWorkbenchWindowActionDelegate { public AttachToProcess() { } @Override public void run(IAction action) { try { doIt(); } catch (Exception e) { Log.log(e); PyDialogHelpers.openCritical("Error attaching to process", e.getMessage()); } } protected void doIt() throws Exception { IProcessList processList = PlatformUtils.getProcessList(); IProcessInfo[] processList2 = processList.getProcessList(); TreeNode<Object> root = new TreeNode<Object>(null, null); for (IProcessInfo iProcessInfo : processList2) { new TreeNode<>(root, iProcessInfo); } TreeNode<Object> element = new Select1Dialog() { @Override protected String getInitialFilter() { return "*python*"; }; @Override protected ILabelProvider getLabelProvider() { return new TreeNodeLabelProvider() { @Override public Image getImage(Object element) { return SharedUiPlugin.getImageCache().get(UIConstants.PUBLIC_ATTR_ICON); }; @SuppressWarnings("unchecked") @Override public String getText(Object element) { if (element == null) { return "null"; } TreeNode<Object> node = (TreeNode<Object>) element; Object data = node.data; if (data instanceof IProcessInfo) { IProcessInfo iProcessInfo = (IProcessInfo) data; return iProcessInfo.getPid() + " - " + iProcessInfo.getName(); } return "Unexpected: " + data; }; }; }; }.selectElement(root); if (element != null) { IProcessInfo p = (IProcessInfo) element.data; int pid = p.getPid(); if (!PydevRemoteDebuggerServer.isRunning()) { // I.e.: the remote debugger server must be on so that we can attach to it. PydevRemoteDebuggerServer.startServer(); } //Select interpreter IWorkbenchWindow workbenchWindow = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); IInterpreterManager interpreterManager = PydevPlugin.getPythonInterpreterManager(); if (interpreterManager == null) { MessageDialog.openError(workbenchWindow.getShell(), "No interpreter manager.", "No interpreter manager was available for attaching to a process."); } IInterpreterInfo[] interpreters = interpreterManager.getInterpreterInfos(); if (interpreters == null || interpreters.length == 0) { MessageDialog .openError(workbenchWindow.getShell(), "No interpreters for creating console", "An interpreter that matches the architecture of the target process must be configured in the interpreter preferences."); return; } SelectionDialog listDialog = AbstractInterpreterPreferencesPage.createChooseIntepreterInfoDialog( workbenchWindow, interpreters, "Select interpreter which matches the architecture of the target process (i.e.: 32/64 bits).", false); int open = listDialog.open(); if (open != ListDialog.OK || listDialog.getResult().length != 1) { return; } Object[] result = listDialog.getResult(); IInterpreterInfo interpreter; if (result == null || result.length == 0) { interpreter = interpreters[0]; } else { interpreter = ((IInterpreterInfo) result[0]); } SimplePythonRunner runner = new SimplePythonRunner(); IPath relative = new Path("pysrc").append("pydevd_attach_to_process").append("attach_pydevd.py"); String script = PydevPlugin.getBundleInfo().getRelativePath(relative).getAbsolutePath(); String[] args = new String[] { "--port", "" + DebugPluginPrefsInitializer.getRemoteDebuggerPort(), "--pid", "" + pid }; IPythonNature nature = new SystemPythonNature(interpreterManager, interpreter); String[] s = SimplePythonRunner.preparePythonCallParameters(interpreter.getExecutableOrJar(), script, args); Tuple<Process, String> run = runner.run(s, (File) null, nature, new NullProgressMonitor()); if (run.o1 != null) { ShowProcessOutputDialog dialog = new ShowProcessOutputDialog(UIUtils.getActiveShell(), run.o1); dialog.open(); } } } @Override public void selectionChanged(IAction action, ISelection selection) { } @Override public void dispose() { } @Override public void init(IWorkbenchWindow window) { } }