Start a process as an another user using JNA (Windows) Tag(s): JNA/JNI
JNA (Java Native Access) provides Java programs easy access to native shared libraries (DLLs on Windows) without writing anything but Java code - no JNI or native code is required.
We use the CreateProcessWithLogin API to start a process as a different user. We need to provide the credentials (username/password and domain (if required)).
First we define the interface.
import com.sun.jna.Native; import com.sun.jna.Pointer; import com.sun.jna.WString; import com.sun.jna.platform.win32.Advapi32; import com.sun.jna.platform.win32.WinBase.PROCESS_INFORMATION; import com.sun.jna.platform.win32.WinBase.STARTUPINFO; // https://github.com/twall/jna#readme // you need 2 jars : jna-3.5.1.jar and platform-3.5.1.jar public interface MoreAdvApi32 extends Advapi32 { MoreAdvApi32 INSTANCE = (MoreAdvApi32) Native.loadLibrary("AdvApi32", MoreAdvApi32.class); /* * BOOL WINAPI CreateProcessWithLogonW( __in LPCWSTR lpUsername, * __in_opt LPCWSTR lpDomain, __in LPCWSTR lpPassword, __in DWORD * dwLogonFlags, __in_opt LPCWSTR lpApplicationName, __inout_opt LPWSTR * lpCommandLine, __in DWORD dwCreationFlags, __in_opt LPVOID * lpEnvironment, __in_opt LPCWSTR lpCurrentDirectory, __in * LPSTARTUPINFOW lpStartupInfo, __out LPPROCESS_INFORMATION * lpProcessInfo ); */ // http://msdn.microsoft.com/en-us/library/windows/desktop/ms682431%28v=vs.85%29.aspx boolean CreateProcessWithLogonW (WString lpUsername, WString lpDomain, WString lpPassword, int dwLogonFlags, WString lpApplicationName, WString lpCommandLine, int dwCreationFlags, Pointer lpEnvironment, WString lpCurrentDirectory, STARTUPINFO lpStartupInfo, PROCESS_INFORMATION lpProcessInfo); public static final int LOGON_WITH_PROFILE = 0x00000001; public static final int LOGON_NETCREDENTIALS_ONLY = 0x00000002; int CREATE_NO_WINDOW = 0x08000000; int CREATE_UNICODE_ENVIRONMENT = 0x00000400; int CREATE_NEW_CONSOLE = 0x00000010; int DETACHED_PROCESS = 0x00000008; }
import com.sun.jna.WString; import com.sun.jna.platform.win32.Kernel32; import com.sun.jna.platform.win32.Kernel32Util; import com.sun.jna.platform.win32.WinBase.PROCESS_INFORMATION; import com.sun.jna.platform.win32.WinBase.STARTUPINFO; public class CreateProcessAsUser { public static void main(String ... args ) { WString nullW = null; PROCESS_INFORMATION processInformation = new PROCESS_INFORMATION(); STARTUPINFO startupInfo = new STARTUPINFO(); boolean result = MoreAdvApi32.INSTANCE.CreateProcessWithLogonW (new WString("username"), // user nullW, // domain , null if local new WString("password"), // password MoreAdvApi32.LOGON_WITH_PROFILE, // dwLogonFlags nullW, // lpApplicationName new WString("c:\\windows\\system32\\cmd.exe"), // command line MoreAdvApi32.CREATE_NEW_CONSOLE, // dwCreationFlags null, // lpEnvironment new WString("C:\\temp\\test"), // directory startupInfo, processInformation); if (!result) { int error = Kernel32.INSTANCE.GetLastError(); System.out.println("OS error #" + error); System.out.println(Kernel32Util.formatMessageFromLastErrorCode(error)); } } }