简体   繁体   English

从C#控制台应用程序杀死Java进程

[英]Killing Java Process from C# Console App

I posted about this a little while ago, but I resolved the other issue and ran into one more. 我前不久发布了有关此内容的文章,但我解决了另一个问题,然后又遇到了另一个问题。 I am about to deploy this program to 28 hosting machines so I want to make sure this is working before I do so. 我即将将该程序部署到28台托管计算机上,因此在执行此操作之前,请确保它可以正常运行。

I wrote a little c# NET application that is basically a wrapper for a Java application, when my app starts, the Java app starts, when my app closes, it closes, and so on. 我编写了一个小的c#NET应用程序,它基本上是Java应用程序的包装,当我的应用程序启动时,Java应用程序启动,当我的应用程序关闭时,它关闭,依此类推。

Everything works properly except that when I close my application, the Java application continues to run. 一切正常,除了当我关闭应用程序时,Java应用程序继续运行。 When I create the process, I store the Process var in a variable outside of the methods, and then use that when my application goes to shutdown. 创建流程时,我将Process var存储在方法之外的变量中,然后在应用程序关闭时使用该变量。 For whatever reason though it is not terminating the Java application. 无论出于何种原因,它都不会终止Java应用程序。

class Program
{
    private static Process minecraftProcess;

    public static void LaunchMinecraft(String file, String memoryValue)
    {
        String memParams = "-Xmx" + memoryValue + "M" + " -Xms" + memoryValue + "M ";
        String args = memParams + "-jar " + file + " nogui";
        ProcessStartInfo processInfo = new ProcessStartInfo("java.exe", args);
        processInfo.CreateNoWindow = true;
        processInfo.UseShellExecute = false;

        try
        {
            //using (Process minecraftProcess = Process.Start(processInfo))
            using (minecraftProcess = Process.Start(processInfo))
            {
                minecraftProcess.WaitForExit();
            }
        }
        catch
        {
            // Log Error
        }
    }

    static void Main(string[] args)
    {
        Arguments CommandLine = new Arguments(args);

        // Hook ProcessExit Event
        AppDomain.CurrentDomain.ProcessExit += new EventHandler(Current_ProcessExit);

        if (CommandLine["file"] != null && CommandLine["memory"] != null)
        {
            // Launch the Application (Command Line Parameters)
            LaunchMinecraft(CommandLine["file"], CommandLine["memory"]);
        }
        else
        {
            // Launch the Application (Default Parameters)
            LaunchMinecraft("minecraft_server.jar", "1024");
        }
    }

    static void Current_ProcessExit(object sender, EventArgs e)
    {
        System.Threading.Thread.Sleep(10000);

        // If we have an active Minecraft Service, Shut it down
        if (minecraftProcess != null)
        {
            minecraftProcess.Kill();
        }
    }
}

You can't Sleep in a ProcessExit handler. 您无法在ProcessExit处理程序中Sleep

The documentation states: 文档指出:

The total execution time of all ProcessExit event handlers is limited, just as the total execution time of all finalizers is limited at process shutdown. 所有ProcessExit事件处理程序的总执行时间是有限的,就像所有终结器的总执行时间在进程关闭时是有限的一样。 The default is two seconds. 默认值为两秒钟。 An unmanaged host can change this execution time by calling the ICLRPolicyManager::SetTimeout method with the OPR_ProcessExit enumeration value. 非托管主机可以通过调用带有OPR_ProcessExit枚举值的ICLRPolicyManager :: SetTimeout方法来更改此执行时间。

没关系,我只是意识到minecraftProcess变量是静态的。

Don't know if you did not solve this issue by yourself but: 不知道您是否不是自己解决此问题,而是:

  • You should be aware that there are Start methods for instances (returning bool) and static (returning a object). 您应该意识到,实例(返回布尔值)和静态(返回对象)都有Start方法。

  • You should not use using with something other than using-local variables! 除了使用局部变量之外,您不应该将using与其他东西一起使用!

Just this should work fine: 只是这应该工作正常:

minecraftProcess = Process.Start(processInfo)
minecraftProcess.WaitForExit();

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

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