Question

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. From code it give 5412 as process.id and 1029 as process.Handle where as 6424 is the process id of java.exe
Is there any other method from I can get same Process ID which is in the TaskManager

NOTE procName is the path to a Bat file in which it run a jar file.

EDITED

When I execute the following code it gives the error from process.Kill() line.

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

Cannot process request because the process (6504) has exited

Was it helpful?

Solution

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);
  }

OTHER TIPS

You have to iterate all running process. Then kill all processes with the parentProcess is your cmd.exe Process. Here a code sample.

using System.Diagnostics;

using 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

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.

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

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

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top