如何从Process.start()获取进程ID

时间:2014-05-02 11:09:21

标签: c# process

我有以下代码

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;

使用此代码我将 cmd 作为进程名称,在taskManager中显示为 java.exe 。从代码中, 5412 process.id 1029 process.Handle,其中 6424 java.exe
是否还有其他任何方法我可以在TaskManager中获得相同的进程ID

注意 procName是运行jar文件的Bat文件的路径。

EDITED

当我执行以下代码时,它会从process.Kill()行给出错误。

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

无法处理请求,因为进程(6504)已退出

3 个答案:

答案 0 :(得分:2)

这是我的代码段

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

答案 1 :(得分:0)

您必须迭代所有正在运行的进程。然后使用parentProcess杀死所有进程是您的cmd.exe进程。这是一个代码示例。

using System.Diagnostics;

使用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();
        }
    }

答案 2 :(得分:0)

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

注意,如果你不想使用try..catch,你必须使用WaitForExit()或HasExited 等待终止完成,否则您可能会看到&#34;进程已退出&#34;例外。

更多详情How to kill a process without getting a "process has exited" exception?

2)如果你应该使用bat文件,那么从Kill process tree programmatically in C#获取KillProcessAndChildren()方法(需要对System.Management的引用)并调用

KillProcessAndChildren(javaProcessID); 

它将杀死主进程及其所有子进程。

3)当然,您仍然可以使用原始代码并按名称

枚举所有流程
Process[] pp = Process.GetProcessesByName("java");
foreach (Process p in pp) 
    p.Kill();

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

但如果你有多个java / cmd进程,这将删除所有这些可能不是一个好主意。