How to get Windows username in Java?
So what I am trying to do is let my Java find the user’s name that windows is logged in with, so when I would say such a method, it would return the users name, like I use it in the User called Noah, java would return «Noah» and if I were on the user Amanda, Java would return «Amanda». How would I do this?
4 Answers 4
Lookup the system property «user.name».
String username = System.getProperty("user.name");
c:\dev\src\misc>javac Main.java c:\dev\src\misc>java Main rgettman c:\dev\src\misc>
The environment variable USERNAME might be available on different versions of Windows, but it is NOT available by default on macOS (checked Catalina) or Linux/GNU (checked Linux Mint). You’d need to check USER instead on those systems.
String userName = System.getProperty("user.name");
String userName = new com.sun.security.auth.module.NTSystem().getName()
I like this response because when some java apps run as a Windows service, System.getProperty(«user.name») returns «SYSTEM» if the service started before the user logged in and not the currently logged user at the time the call is made. NTSystem.getName() returns the currently logged username at the time of the call. The native method is useful in implementing logic that is Windows specific and where people run into user «SYSTEM» returned by System.getProperty(«user.name») when running as a windows service.
@SanjivJivan For me new NTSystem().getName() returns SYSTEM running as a windows service with jre1.8.0_201 before any and also after log on with a windows user.
Be aware that using System.getProperty(«user.name»); is not safe, it is very easy to spoof, like using -Duser.name=Admin or changing it in the command line.
Getting active window information in Java
I am trying to upgrade my application in Java to work only if a window of process with certain name is active. I have found out that this is possible by using JNI, but I have no idea how exactly to do that. I just could not find any description or example that would explain it. My question is — how to get process name of currently active window in Windows (via JNI, or anything else — I accept any another solution)?
JNA (Java Native Access) is easier to use than JNI, but for either of them, JNI or JNA, you have to study how to use them via their tutorials and references and then you have to look through the window API for the proper function call. There are no short-cuts here.
3 Answers 3
Save yourself some pain and use JNA. You will need to download jna.jar and jna-platform.jar for the Win32 API. The pinvoke wiki and MSDN are useful for finding the right system calls.
Anyway, here is the code to print the title and process of the currently active window.
import static enumeration.EnumerateWindows.Kernel32.*; import static enumeration.EnumerateWindows.Psapi.*; import static enumeration.EnumerateWindows.User32DLL.*; import com.sun.jna.Native; import com.sun.jna.Pointer; import com.sun.jna.platform.win32.WinDef.HWND; import com.sun.jna.ptr.PointerByReference; public class EnumerateWindows < private static final int MAX_TITLE_LENGTH = 1024; public static void main(String[] args) throws Exception < char[] buffer = new char[MAX_TITLE_LENGTH * 2]; GetWindowTextW(GetForegroundWindow(), buffer, MAX_TITLE_LENGTH); System.out.println("Active window title: " + Native.toString(buffer)); PointerByReference pointer = new PointerByReference(); GetWindowThreadProcessId(GetForegroundWindow(), pointer); Pointer process = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, false, pointer.getValue()); GetModuleBaseNameW(process, null, buffer, MAX_TITLE_LENGTH); System.out.println("Active window process: " + Native.toString(buffer)); >static class Psapi < static < Native.register("psapi"); >public static native int GetModuleBaseNameW(Pointer hProcess, Pointer hmodule, char[] lpBaseName, int size); > static class Kernel32 < static < Native.register("kernel32"); >public static int PROCESS_QUERY_INFORMATION = 0x0400; public static int PROCESS_VM_READ = 0x0010; public static native int GetLastError(); public static native Pointer OpenProcess(int dwDesiredAccess, boolean bInheritHandle, Pointer pointer); > static class User32DLL < static < Native.register("user32"); >public static native int GetWindowThreadProcessId(HWND hWnd, PointerByReference pref); public static native HWND GetForegroundWindow(); public static native int GetWindowTextW(HWND hWnd, char[] lpString, int nMaxCount); > >
Get current active window’s title in Java
I am trying to write a Java program that logs what application I’m using every 5 seconds (this is a time tracker app). I need some way to find out what the current active window is. I found KeyboardFocusManager.getGlobalActiveWindow() but I can’t get it to work right. A cross platform solution is preferable, but if one doesn’t exist, then I’m developing for linux with X.Org. Thanks.
Are you using a windowing system like KDE or Gnome? It may be necessary to know that since this kind of task usually needs to be done with system-specific code.
6 Answers 6
I’m quite certain that you’ll find there’s no way to enumerate the active windows in pure Java (I’ve looked pretty hard before), so you’ll need to code for the platforms you want to target.
- On Mac OS X, you can launch an AppleScript using «osascript».
- On X11, you can use xwininfo.
- On Windows, you can probably launch some VBScript (e.g. this link looks promising).
If you’re using SWT, you may be able to find some undocumented, non-public methods in the SWT libs, since SWT provides wrappers for a lot of the OS API’s (e.g. SWT on Cocoa has the org.eclipse.swt.internal.cocoa.OS#objc_msgSend() methods that can be used to access the OS). The equivalent «OS» classes on Windows and X11 may have API’s you can use.
I have written a java program using user361601’s script. I hope this will help others.
import java.io.BufferedReader; import java.io.InputStreamReader; public class WindowAndProcessInfo4Linux < public static final String WIN_ID_CMD = "xprop -root | grep " + "\"_NET_ACTIVE_WINDOW(WINDOW)\"" + "|cut -d ' ' -f 5"; public static final String WIN_INFO_CMD_PREFIX = "xwininfo -id "; public static final String WIN_INFO_CMD_MID = " |awk \'BEGIN /xwininfo: Window id/\' | sed \'s/-[^-]*$//g\'"; public String execShellCmd(String cmd)< try < Runtime runtime = Runtime.getRuntime(); Process process = runtime.exec(new String[] < "/bin/bash", "-c", cmd >); int exitValue = process.waitFor(); System.out.println("exit value: " + exitValue); BufferedReader buf = new BufferedReader(new InputStreamReader(process.getInputStream())); String line = ""; String output = ""; while ((line = buf.readLine()) != null) < output = line; >return output; > catch (Exception e) < System.out.println(e); return null; >> public String windowInfoCmd(String winId) < if(null!=winId && !"".equalsIgnoreCase(winId))< return WIN_INFO_CMD_PREFIX+winId +WIN_INFO_CMD_MID; >return null; > public static void main (String [] args) < WindowAndProcessInfo4Linux windowAndProcessInfo4Linux = new WindowAndProcessInfo4Linux(); try < Thread.sleep(4000); >catch (InterruptedException e) < // TODO Auto-generated catch block e.printStackTrace(); >String winId = windowAndProcessInfo4Linux.execShellCmd(WIN_ID_CMD); String winInfoMcd = windowAndProcessInfo4Linux.windowInfoCmd(winId); String windowTitle = windowAndProcessInfo4Linux.execShellCmd(winInfoMcd); System.out.println("window title is: "+ windowTitle); > >
// the thread.sleep is there so that you get time to switch to other window 🙂 also, you may use quartz from spring to schedule it.
How do I get the active window’s application’s name with JNA?
I’ve found that GetWindowModuleFilename doesn’t really work most of the time. QueryFullProcessImageName , however, works just fine. Note that you still do need to OpenProcess the process to access the image file name.
Try this in a console application. It will print out the active window’s image filename when you change the window.
import com.sun.jna.platform.win32.*; import com.sun.jna.platform.win32.WinDef.HWND; import com.sun.jna.platform.win32.WinNT.HANDLE; import com.sun.jna.ptr.IntByReference; public class Main < public static void main(String[] args) throws Exception < HWND prevFg = null; while (true) < Thread.sleep(200); HWND fg = User32.INSTANCE.GetForegroundWindow(); // don't print the name if it's still the same window as previously if (fg.equals(prevFg)) < continue; >String fgImageName = getImageName(fg); if (fgImageName == null) < System.out.println("Failed to get the image name!"); >else < System.out.println(fgImageName); >prevFg = fg; > > private static String getImageName(HWND window) < // Get the process ID of the window IntByReference procId = new IntByReference(); User32.INSTANCE.GetWindowThreadProcessId(window, procId); // Open the process to get permissions to the image name HANDLE procHandle = Kernel32.INSTANCE.OpenProcess( Kernel32.PROCESS_QUERY_LIMITED_INFORMATION, false, procId.getValue() ); // Get the image name char[] buffer = new char[4096]; IntByReference bufferSize = new IntByReference(buffer.length); boolean success = Kernel32.INSTANCE.QueryFullProcessImageName(procHandle, 0, buffer, bufferSize); // Clean up: close the opened process Kernel32.INSTANCE.CloseHandle(procHandle); return success ? new String(buffer, 0, bufferSize.getValue()) : null; >>
Clicking around my windows, the program prints out lines like these:
C:\Program Files\JetBrains\IntelliJ IDEA Community Edition 2017.3.5\bin\idea64.exe C:\Program Files (x86)\Google\Chrome\Application\chrome.exe C:\Program Files\JetBrains\IntelliJ IDEA Community Edition 2017.3.5\bin\idea64.exe