codythecoder
codythecoder

Reputation:

Programmatically (in C#) get java application name from javaw.exe process?

Is there a way to get name of the java app associated with a javaw.exe? Basically I need to write a tool, to check (daily) if a specific java app is running on our server (and if not the tool will email me).

I would like to do this in C#...but if there isn't a way I would be open to other suggestions.

I have read this question 265794 but that is more about modifying the java app itself...do all java app's really appear as javaw.ex, unless 'wrapped'??

Upvotes: 2

Views: 3435

Answers (5)

martinwang1985
martinwang1985

Reputation: 556

I agree with mheyman I have modified a little his code

using (var mos = new ManagementObjectSearcher( "SELECT * FROM Win32_Process"))

I used "select *"

Upvotes: 0

mheyman
mheyman

Reputation: 4325

I've used the following function to find a java program by passing in identifying command line arguments like the path to the java executable and the class called and maybe a jar name or a property definition or two just to be sure. Once you have a process id, it is simple to create a Process using Process.GetProcessByValue(id) but you don't need that for your code, just check the returned id.HasValue.

/// <summary>
/// Return the first process id with matching values in the command line.
/// </summary>
/// <param name="args">
/// Values in the command line to match (case insensitive).
/// </param>
/// <returns>
/// The process id of the first matching process found; null on no match.
/// </returns>
public static int? ProcessIdOf(params string[] args)
{
    using (var mos = new ManagementObjectSearcher(
        "SELECT ProcessId,CommandLine FROM Win32_Process"))
    {
        foreach (ManagementObject mo in mos.Get())
        {
            var commandLine = (string)mo["CommandLine"] ?? string.Empty;
            for (int i = 0;; ++i)
            {
                if (i == args.Length)
                {
                    return int.Parse(mo["ProcessId"].ToString());
                }

                if (commandLine.IndexOf(
                       args[i], 
                       StringComparison.InvariantCultureIgnoreCase) == -1)
                {
                    break;
                }
            }
        }
    }

    return null;
}

Some oddities in this code - I don't use the SELECT x,y FROM z WHERE y LIKE "%z%" construct because I didn't want to bother dealing with escape characters. Also, I don't really know what type a ProcessId is so I just cast it to a string and parse it as an int - I think I tried to do an unchecked cast to int and that threw an exception (from here it is supposed to be a uin32). The code above works.

Upvotes: 2

user156178
user156178

Reputation: 61

You can find the list of running java applications under this folder: system-temp-folder/hsperfdata_user where system-temp-folder is the path to your system temp folder and user is the user that run the process. When a java process starts, it creates a file in that folder with the process-id as the name of the file. Each files containes binary data (including process name, i think). However, I think this is hard to read that binary file in C#. To find the process name you have two different solutions: First, you can use C# and system calls to find the process name (I don't know how you can do that in C#) Second, if you have access to a jdk folder, you may run jps and get the output. Actually, jps reads the files I have already mentioned and writes some human readable data to console.

Upvotes: 0

Promit
Promit

Reputation: 3507

Well, the main class gets passed to javaw as a command line parameter, right? So if you use the info in this SO post, you should be able to find out what it's running.

Upvotes: 0

Brian Agnew
Brian Agnew

Reputation: 272277

Check out jps. That will list the VMs running on your system, and identify the jar file or class invoked.

Upvotes: 3

Related Questions