简体   繁体   English

如何从Process.start()获取processID

[英]How to get processID from Process.start()

I have the Following Code 我有以下代码

log.Info("Starting jar");
System.Diagnostics.ProcessStartInfo si = new ProcessStartInfo(procName);
si.RedirectStandardOutput = true;
si.RedirectStandardError = true;
si.UseShellExecute = false;
si.CreateNoWindow = false;
si.WorkingDirectory = System.IO.Directory.GetParent(Application.ExecutablePath) + "\\" + Properties.Settings.Default.rootDirectory;

//start a new process for Client
Process process = new Process();
process.StartInfo = si;
process.Start();
String name = process.ProcessName;
javaClientProcessId = process.Handle;
int javaProcessID = process.Id;

by using this code I am getting cmd as process name where in taskManager it showing as java.exe . 通过使用此代码我得到cmd作为进程名称在taskManager中显示为java.exe From code it give 5412 as process.id and 1029 as process.Handle where as 6424 is the process id of java.exe 从代码中,它将5412作为process.id ,将1029作为process.Handle ,其中6424java.exe的进程ID
Is there any other method from I can get same Process ID which is in the TaskManager 是否有任何其他方法可以获得TaskManager中的相同进程ID

NOTE procName is the path to a Bat file in which it run a jar file. 注意 procName是运行jar文件的Bat文件的路径。

EDITED EDITED

When I execute the following code it gives the error from process.Kill() line. 当我执行以下代码时,它会从process.Kill()行给出错误。

if (process != null)
{
     process.Kill();
     process.Close();
     process.Dispose();
}

Cannot process request because the process (6504) has exited 由于进程(6504)已退出,因此无法处理请求

Here is my code snippet 这是我的代码片段

try
{
    Process[] javaProcList = Process.GetProcessesByName("java");
    foreach (Process javaProc in javaProcList)
    {
        javaProc.Kill();
        javaProc.Close();
        javaProc.Dispose();

        Console.WriteLine("StopJar -Java Process Stopped ");
        log.Debug("StopJar -Java Process Stopped ");
     }
 }
 catch (Exception exp)
 {
     log.Error("StopJar - Unable to kill Java Process", exp);
     Console.WriteLine("Error while closing: " + exp.Message);
  }

You have to iterate all running process. 您必须迭代所有正在运行的进程。 Then kill all processes with the parentProcess is your cmd.exe Process. 然后使用parentProcess杀死所有进程是您的cmd.exe进程。 Here a code sample. 这是一个代码示例。

using System.Diagnostics;

using System.Runtime.InteropServices; 使用System.Runtime.InteropServices;

class Program {

    [DllImport("kernel32.dll", SetLastError = true)]
    private static extern IntPtr CreateToolhelp32Snapshot(uint dwFlags, uint th32ProcessID);

    [DllImport("kernel32.dll")]
    private static extern bool Process32First(IntPtr hSnapshot, ref PROCESSENTRY32 lppe);

    [DllImport("kernel32.dll")]
    private static extern bool Process32Next(IntPtr hSnapshot, ref PROCESSENTRY32 lppe);

    [StructLayout(LayoutKind.Sequential)]
    private struct PROCESSENTRY32 {
        public uint dwSize;
        public uint cntUsage;
        public uint th32ProcessID;
        public IntPtr th32DefaultHeapID;
        public uint th32ModuleID;
        public uint cntThreads;
        public uint th32ParentProcessID;
        public int pcPriClassBase;
        public uint dwFlags;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
        public string szExeFile;
    }

    public static class helper {
        public static Process[] getChildProcesses(int parentProcessID) {
            var ret = new List<Process>();
            uint TH32CS_SNAPPROCESS = 2;

            IntPtr hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
            if (hSnapshot == IntPtr.Zero) {
                return ret.ToArray();
            }
            PROCESSENTRY32 procInfo = new PROCESSENTRY32();
            procInfo.dwSize = (uint)Marshal.SizeOf(typeof(PROCESSENTRY32));
            if (Process32First(hSnapshot, ref procInfo) == false) {
                return ret.ToArray();
            }
            do {
                if ((int)procInfo.th32ParentProcessID == parentProcessID) {
                    ret.Add(Process.GetProcessById((int)procInfo.th32ProcessID));
                }
            }
            while (Process32Next(hSnapshot, ref procInfo));

            return ret.ToArray();
        }
        public static void killChildProcesses(int parentProcessID) {
            foreach (var p in getChildProcesses(parentProcessID))
                p.Kill();
        }
    }

1) Try to run java directly without bat file 1)尝试直接运行java而不使用bat文件

Process p = new Process();  
ProcessStartInfo si = new ProcessStartInfo();  
si.Arguments = @"-jar app.jar";  
si.FileName = "java";  
p.StartInfo = si;  
p.Start();  
Console.WriteLine(p.Id);  
if (!p.HasExited) 
   p.Kill();  

Note, that if you do not want to use try..catch you'll have to use WaitForExit() or HasExited to wait for termination to complete, otherwise you might see that "process has exited" exception again. 请注意,如果您不想使用try..catch,则必须使用WaitForExit()或HasExited等待终止完成,否则您可能会再次看到“进程已退出”异常。

More details How to kill a process without getting a "process has exited" exception? 更多细节如何在没有“进程退出”异常的情况下终止进程?

2) If you should use a bat-file then get the KillProcessAndChildren() method from Kill process tree programmatically in C# (required a reference to System.Management) and call 2)如果你应该使用bat文件,那么在C#中以编程方式从Kill进程树中获取KillProcessAndChildren()方法(需要对System.Management的引用)并调用

KillProcessAndChildren(javaProcessID); 

It will kill main process, and all its children. 它将杀死主要进程及其所有子进程。

3) And of course, you can still use your original code and enumerate all processes by name 3)当然,您仍然可以使用原始代码并按名称枚举所有进程

Process[] pp = Process.GetProcessesByName("java");
foreach (Process p in pp) 
    p.Kill();

pp = Process.GetProcessesByName("cmd");
foreach (Process p in pp)
    p.Kill();

but if you have multiple processes of java/cmd, this will delete all of them which might be not a good idea. 但如果你有多个java / cmd进程,这将删除所有可能不是一个好主意的进程。

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

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