Мне нужно запустить приложение в Windows с правами администратора на рабочем столе другого пользователя.
Я запускаю свой код как администратор с повышенными правами.
Я нашел эту статью (она описывает, как это сделатьэто на .net):
https://www.codeproject.com/Articles/35773/Subverting-Vista-UAC-in-Both-32-and-64-bit-Archite
Я перевел код из статьи на Java, но advapi32.CreateProcessAsUser возвращает false.Кто-нибудь видит, что я пропустил в этом коде?
зависимости pom
<dependencies>
<dependency>
<groupId>net.java.dev.jna</groupId>
<artifactId>jna</artifactId>
<version>5.2.0</version>
</dependency>
<dependency>
<groupId>net.java.dev.jna</groupId>
<artifactId>jna-platform</artifactId>
<version>5.2.0</version>
</dependency>
</dependencies>
мой код
import com.sun.jna.platform.win32.*;
public class Test {
public static void main(String[] args) {
// id of the process which we you as a pointer to the target desktop where we will open new application from current user
int procId = 26100;
String applicationName = "C:\\Windows\\System32\\cmd.exe";
Kernel32 kernel32 = Kernel32.INSTANCE;
int securityLevel = WinNT.READ_CONTROL;
final int PROCESS_VM_READ=0x0010;
final int PROCESS_QUERY_INFORMATION=0x0400;
WinNT.HANDLE hProcess = kernel32.OpenProcess(PROCESS_VM_READ | PROCESS_QUERY_INFORMATION, false, procId);
System.out.println(hProcess);
Advapi32 advapi32 = Advapi32.INSTANCE;
// obtain a handle to the access token of the winlogon process
WinNT.HANDLEByReference hPToken = new WinNT.HANDLEByReference();
if (!advapi32.OpenProcessToken(hProcess, WinNT.TOKEN_DUPLICATE, hPToken)) {
kernel32.CloseHandle(hProcess);
throw new RuntimeException("1");
}
System.out.println(hPToken);
// Security attibute structure used in DuplicateTokenEx and CreateProcessAsUser
// I would prefer to not have to use a security attribute variable and to just
// simply pass null and inherit (by default) the security attributes
// of the existing token. However, in C# structures are value types and therefore
// cannot be assigned the null value.
WinBase.SECURITY_ATTRIBUTES sa = new WinBase.SECURITY_ATTRIBUTES();
sa.dwLength = new WinDef.DWORD(sa.size());
WinNT.HANDLEByReference hUserTokenDup = new WinNT.HANDLEByReference();
// copy the access token of the winlogon process;
// the newly created token will be a primary token
if (!advapi32.DuplicateTokenEx(hPToken.getValue(), securityLevel, sa,
(int) WinNT.SECURITY_IMPERSONATION_LEVEL.SecurityIdentification,
(int) WinNT.TOKEN_TYPE.TokenPrimary, hUserTokenDup)) {
kernel32.CloseHandle(hProcess);
kernel32.CloseHandle(hPToken.getValue());
throw new RuntimeException("2");
}
System.out.println(hUserTokenDup);
WinBase.STARTUPINFO si = new WinBase.STARTUPINFO();
si.cb = new WinDef.DWORD(si.size());
// interactive window station parameter; basically this indicates
// that the process created can display a GUI on the desktop
si.lpDesktop = "winsta0\\default";
final int NORMAL_PRIORITY_CLASS = 0x0020;
final int CREATE_NEW_CONSOLE = 0x0010;
// flags that specify the priority and creation method of the process
int dwCreationFlags = NORMAL_PRIORITY_CLASS | CREATE_NEW_CONSOLE;
WinBase.PROCESS_INFORMATION procInfo = new WinBase.PROCESS_INFORMATION();
// create a new process in the current User's logon session
boolean result = advapi32.CreateProcessAsUser(
hUserTokenDup.getValue(), // client's access token
null, // file to execute
applicationName, // command line
sa, // pointer to process SECURITY_ATTRIBUTES
sa, // pointer to thread SECURITY_ATTRIBUTES
false, // handles are not inheritable
dwCreationFlags, // creation flags
null, // pointer to new environment block
null, // name of current directory
si, // pointer to STARTUPINFO structure
procInfo // receives information about new process
);
System.out.println(procInfo);
System.out.println("result: " + result);
}
}