简体   繁体   English

我如何获取由cmd行启动(由我启动)的进程的进程ID?

[英]How do I get the process ID of a process that is started by cmd line (which is started by me)?

So, I use my own .NET Process to start up a command line process like so: ProcessStartInfo startInfo = new ProcessStartInfo(); 因此,我使用自己的.NET进程来启动命令行进程,如下所示: ProcessStartInfo startInfo = new ProcessStartInfo();

  Process p = new Process(); startInfo.CreateNoWindow = true; startInfo.RedirectStandardOutput = redirectOutput; startInfo.RedirectStandardError = redirectError; //startInfo.WindowStyle = ProcessWindowStyle.Hidden; //is this necessary for cmd line commands? startInfo.RedirectStandardInput = false; startInfo.UseShellExecute = false; String arguments = "/C PYTHON_SCRIPT"; startInfo.Arguments = arguments; String pathToProcess = "cmd.exe"; startInfo.FileName = pathToProcess; startInfo.WorkingDirectory = workingDirectory; p.StartInfo = startInfo; p.Start(); 

The process executes just fine, and I get its output/errors. 该过程执行得很好,我得到了它的输出/错误。 The problem comes when I want to kill it off before it is finished executing. 当我想在执行完成之前将其杀死时,问题就来了。 Since cmd line technically started off the "PYTHON_SCRIPT" process itself, I don't know what the Process ID of that process is! 由于cmd行从技术上是从“ PYTHON_SCRIPT”进程本身开始的,所以我不知道该进程的进程ID是什么! Since that's the one I really want to kill off (not cmd line), I'm screwed. 由于那是我真正想要杀死的那个(不是cmd线),所以我很困惑。 I have in fact killed off the cmd line process to see if it has any effect, and it doesn't. 实际上,我已经取消了cmd行进程,以查看它是否有效果,并且没有效果。

Any help would be appreciated. 任何帮助,将不胜感激。

In case it wasn't clear, the question is: "How do I kill off the PYTHON_SCRIPT (or any other) process?" 如果不清楚,问题是:“我该如何终止PYTHON_SCRIPT(或任何其他)进程?”

EDIT: I'm sorry I wasn't clear... I'm using PYTHON_SCRIPT as a filler. 编辑:对不起,我不清楚...我正在使用PYTHON_SCRIPT作为填充物。 I am starting many different processes this way, not all of which are python scripts. 我以这种方式开始了许多不同的过程,但并非全部都是python脚本。 Some are batch files, some are python scripts, some are perl scripts, etc. I would much prefer a generalized solution here. 有些是批处理文件,有些是python脚本,有些是perl脚本,等等。我在这里更喜欢通用的解决方案。

EDIT 2: The situation is a little more complex than it might appear from the question. 编辑2:这种情况比问题中出现的情况要复杂得多。 For instance, I am using scons to build some code. 例如,我正在使用scons来构建一些代码。 Using "cmd /C scons" is easy. 使用“ cmd / C scons”很容易。 However, starting the scons process is much more difficult, because it is a python script. 但是,启动scons流程要困难得多,因为它是python脚本。 I pass in a different working directory, so "python.exe scons.py scons" won't work at all, and neither will "scons.bat scons" since scons.bat needs to find scons.py, and scons.py isn't in my working directory. 我传入了另一个工作目录,因此“ python.exe scons.py scons”根本不起作用,“ scons.bat scons”也不会工作,因为scons.bat需要找到scons.py,而scons.py是不在我的工作目录中。

Finally found the answer through much perseverance and google foo! 终于通过毅力和Google foo找到了答案! Here is a link to the stackoverflow answer: 这是stackoverflow答案的链接:

https://stackoverflow.com/a/15281070/476298 https://stackoverflow.com/a/15281070/476298

And here is the website that pointed me in that direction: 这是向我指出这一方向的网站:

http://stanislavs.org/stopping-command-line-applications-programatically-with-ctrl-c-events-from-net/ http://stanislavs.org/stopping-command-line-applications-programatically-with-ctrl-c-events-from-net/

Looks like he did a whole bunch of research on this. 看起来他对此做了很多研究。 Definitely want to give him all the credit. 绝对想给他所有的荣誉。 Hope this page helps others who haven't found it yet! 希望此页面能帮助尚未找到它的其他人!

I had a little trouble figuring out some of the D11Import stuff for the WinAPI methods, so here's the code I used in case anyone else gets hung up: 我在为WinAPI方法找出一些D11Import内容时遇到了一些麻烦,因此这是我在其他人挂断电话时使用的代码:



        [DllImport("kernel32.dll", SetLastError = true)]
        static extern bool AttachConsole(uint dwProcessId);

        [DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)]
        static extern bool FreeConsole();

        // Delegate type to be used as the Handler Routine for SCCH
        delegate Boolean ConsoleCtrlDelegate(CtrlTypes CtrlType);

        [DllImport("kernel32.dll")]
        static extern bool SetConsoleCtrlHandler(ConsoleCtrlDelegate HandlerRoutine, bool Add);

        // Enumerated type for the control messages sent to the handler routine
        enum CtrlTypes : uint
        {
            CTRL_C_EVENT = 0,
            CTRL_BREAK_EVENT,
            CTRL_CLOSE_EVENT,
            CTRL_LOGOFF_EVENT = 5,
            CTRL_SHUTDOWN_EVENT
        }

        [DllImport("kernel32.dll")]
        [return: MarshalAs(UnmanagedType.Bool)]
        private static extern bool GenerateConsoleCtrlEvent(CtrlTypes dwCtrlEvent, uint dwProcessGroupId);

        /// 
        /// Immediately halts all running processes under this ProcessManager's control.
        /// 
        public static void HaltAllProcesses()
        {
            for (int i = 0; i < runningProcesses.Count; i++)
            {
                Process p = runningProcesses[i];
                uint pid = (uint)p.Id;
                //This does not require the console window to be visible.
                if (AttachConsole(pid))
                {
                    //Disable Ctrl-C handling for our program
                    SetConsoleCtrlHandler(null, true);
                    GenerateConsoleCtrlEvent(CtrlTypes.CTRL_C_EVENT, 0);

                    //Must wait here. If we don't and re-enable Ctrl-C
                    //handling below too fast, we might terminate ourselves.
                    p.WaitForExit(2000);

                    FreeConsole();

                    //Re-enable Ctrl-C handling or any subsequently started
                    //programs will inherit the disabled state.
                    SetConsoleCtrlHandler(null, false);
                }

                if (!p.HasExited)
                { //for console-driven processes, this won't even do anything... (it'll kill the cmd line, but not the actual process)
                    try
                    {
                        p.Kill();
                    }
                    catch (InvalidOperationException e) 
                    {
                        controller.PrintImportantError("Process " + p.Id + " failed to exit! Error: " + e.ToString());
                    }
                }
            }
         }

PS If it's not obvious from the code, I'm storing a list of multiple processes that are running simultaneously, and just looping through them one by one to kill them all. PS:如果从代码中看不出来,我将存储同时运行的多个进程的列表,然后逐个循环将其杀死。

if you can run a CMD process, and you know your processes PIDs, why don't you simply use TASKKILL /PID 1234 ? 如果您可以运行CMD进程,并且知道进程的PID,那么为什么不简单地使用TASKKILL /PID 1234

What I didn't get here is where you're getting the PID from. 我没有在这里得到的是您从中获取PID的地方。

This link is very useful 这个连结非常有用

                     // Get the current process.
                Process currentProcess = Process.GetCurrentProcess();


                // Get all instances of Notepad running on the local 
                // computer.
                Process [] localByName = Process.GetProcessesByName("notepad");


                // Get all instances of Notepad running on the specifiec 
                // computer. 
                // 1. Using the computer alias (do not precede with "\\").
                Process [] remoteByName = Process.GetProcessesByName("notepad", "myComputer");

                // 2. Using an IP address to specify the machineName parameter. 
                Process [] ipByName = Process.GetProcessesByName("notepad", "169.0.0.0");


                // Get all processes running on the local computer.
                Process [] localAll = Process.GetProcesses();


                // Get all processes running on the remote computer.
                Process [] remoteAll = Process.GetProcesses("myComputer");


                // Get a process on the local computer, using the process id.
                Process localById = Process.GetProcessById(1234);


                // Get a process on a remote computer, using the process id.
                Process remoteById = Process.GetProcessById(2345,"myComputer");

使用GetProcessesByName()并查找“ python.exe”或“ pythonw.exe”进程。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM