繁体   English   中英

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

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

因此,我使用自己的.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(); 

该过程执行得很好,我得到了它的输出/错误。 当我想在执行完成之前将其杀死时,问题就来了。 由于cmd行从技术上是从“ PYTHON_SCRIPT”进程本身开始的,所以我不知道该进程的进程ID是什么! 由于那是我真正想要杀死的那个(不是cmd线),所以我很困惑。 实际上,我已经取消了cmd行进程,以查看它是否有效果,并且没有效果。

任何帮助,将不胜感激。

如果不清楚,问题是:“我该如何终止PYTHON_SCRIPT(或任何其他)进程?”

编辑:对不起,我不清楚...我正在使用PYTHON_SCRIPT作为填充物。 我以这种方式开始了许多不同的过程,但并非全部都是python脚本。 有些是批处理文件,有些是python脚本,有些是perl脚本,等等。我在这里更喜欢通用的解决方案。

编辑2:这种情况比问题中出现的情况要复杂得多。 例如,我正在使用scons来构建一些代码。 使用“ cmd / C scons”很容易。 但是,启动scons流程要困难得多,因为它是python脚本。 我传入了另一个工作目录,因此“ python.exe scons.py scons”根本不起作用,“ scons.bat scons”也不会工作,因为scons.bat需要找到scons.py,而scons.py是不在我的工作目录中。

终于通过毅力和Google foo找到了答案! 这是stackoverflow答案的链接:

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

这是向我指出这一方向的网站:

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

看起来他对此做了很多研究。 绝对想给他所有的荣誉。 希望此页面能帮助尚未找到它的其他人!

我在为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:如果从代码中看不出来,我将存储同时运行的多个进程的列表,然后逐个循环将其杀死。

如果您可以运行CMD进程,并且知道进程的PID,那么为什么不简单地使用TASKKILL /PID 1234

我没有在这里得到的是您从中获取PID的地方。

这个连结非常有用

                     // 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