createProcessususer函数从服务运行GUI程序
以下是我用来从服务应用程序运行GUI应用程序的代码。我正在传递CMD字符串“ C:\ Windows \ Notepad.exe”。
它没有打开记事本,甚至没有任何错误。即使使用WTSQueryUserToken之后,Htoken也是无效的。 以下是用户创建过程的文档链接: https://lealen.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsathreadsapi-createprocessasusera
private void cpasUser(String cmd) {
HANDLE h = null;
final HANDLEByReference childStdInRead = new HANDLEByReference();
final HANDLEByReference childStdInWrite = new HANDLEByReference();
final HANDLEByReference childStdOutRead = new HANDLEByReference();
final HANDLEByReference childStdOutWrite = new HANDLEByReference();
final int HANDLE_FLAG_INHERIT = 0x00000001;
final int HANDLE_FLAG_PROTECT_FROM_CLOSE = 0x00000002;
final int BUFSIZE = 4096;
final int GENERIC_READ = 0x80000000;
final int FILE_ATTRIBUTE_READONLY = 1;
final int OPEN_EXISTING = 3;
final DWORD STD_OUTPUT_HANDLE = new DWORD(-11);
final int STARTF_USESTDHANDLES = 0x00000100;
String szCmdline = cmd;
PROCESS_INFORMATION processInformation = new PROCESS_INFORMATION();
STARTUPINFO startupInfo = new STARTUPINFO();
startupInfo.cb = new DWORD(processInformation.size());
startupInfo.hStdError = childStdOutWrite.getValue();
startupInfo.hStdOutput = childStdOutWrite.getValue();
startupInfo.hStdInput = childStdInRead.getValue();
startupInfo.dwFlags |= STARTF_USESTDHANDLES;
// Create the child process.
HANDLE hToken = null;
MyWtsapi32 mw = MyWtsapi32.INSTANCE;
mw.WTSQueryUserToken(Kernel32Ext.INSTANCE.WTSGetActiveConsoleSessionId(), hToken) ;
//be sure that the handle is correct ! (can be the issue)
if (hToken == null) logger.info("Token error.");
if (!Advapi32.INSTANCE.CreateProcessAsUser(
hToken,
szCmdline,
null,
null,
null,
true,
32,
null,
null,
startupInfo,
processInformation)){
// System.err.println(Advapi32.INSTANCE.GetLastError());
logger.error("Cannot create process as User ");
logger.error("error code "+Native.getLastError());
}
mywtsapi32.java
public interface MyWtsapi32 extends Wtsapi32 {
// Your own instance to access your functions
MyWtsapi32 INSTANCE = Native.load("Wtsapi32", MyWtsapi32.class, W32APIOptions.DEFAULT_OPTIONS);
// From https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-messagebox
int MB_OK = 0;
// The function to send the message
boolean WTSSendMessageW(HANDLE hServer, int SessionId,
LPWSTR pTitle, int TitleLength,
LPWSTR pMessage, int MessageLength,
int Style, int Timeout, IntByReference pResponse, boolean bWait);
boolean WTSQueryUserToken(long SessionId,HANDLE hServer);
}
强>
public interface Kernel32Ext extends Kernel32{
Kernel32Ext INSTANCE = Native.load("Kernel32",Kernel32Ext.class,W32APIOptions.DEFAULT_OPTIONS);
int WTSGetActiveConsoleSessionId();
}
Below is the code I am using to run a GUI app from service application. I am passing cmd string "C:\Windows\notepad.exe".
It is not opening the Notepad and not even giving any error. hToken is null even after using WTSQueryUserToken.
Here is a documentation link for create process as user : https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-createprocessasusera
private void cpasUser(String cmd) {
HANDLE h = null;
final HANDLEByReference childStdInRead = new HANDLEByReference();
final HANDLEByReference childStdInWrite = new HANDLEByReference();
final HANDLEByReference childStdOutRead = new HANDLEByReference();
final HANDLEByReference childStdOutWrite = new HANDLEByReference();
final int HANDLE_FLAG_INHERIT = 0x00000001;
final int HANDLE_FLAG_PROTECT_FROM_CLOSE = 0x00000002;
final int BUFSIZE = 4096;
final int GENERIC_READ = 0x80000000;
final int FILE_ATTRIBUTE_READONLY = 1;
final int OPEN_EXISTING = 3;
final DWORD STD_OUTPUT_HANDLE = new DWORD(-11);
final int STARTF_USESTDHANDLES = 0x00000100;
String szCmdline = cmd;
PROCESS_INFORMATION processInformation = new PROCESS_INFORMATION();
STARTUPINFO startupInfo = new STARTUPINFO();
startupInfo.cb = new DWORD(processInformation.size());
startupInfo.hStdError = childStdOutWrite.getValue();
startupInfo.hStdOutput = childStdOutWrite.getValue();
startupInfo.hStdInput = childStdInRead.getValue();
startupInfo.dwFlags |= STARTF_USESTDHANDLES;
// Create the child process.
HANDLE hToken = null;
MyWtsapi32 mw = MyWtsapi32.INSTANCE;
mw.WTSQueryUserToken(Kernel32Ext.INSTANCE.WTSGetActiveConsoleSessionId(), hToken) ;
//be sure that the handle is correct ! (can be the issue)
if (hToken == null) logger.info("Token error.");
if (!Advapi32.INSTANCE.CreateProcessAsUser(
hToken,
szCmdline,
null,
null,
null,
true,
32,
null,
null,
startupInfo,
processInformation)){
// System.err.println(Advapi32.INSTANCE.GetLastError());
logger.error("Cannot create process as User ");
logger.error("error code "+Native.getLastError());
}
MyWtsApi32.java
public interface MyWtsapi32 extends Wtsapi32 {
// Your own instance to access your functions
MyWtsapi32 INSTANCE = Native.load("Wtsapi32", MyWtsapi32.class, W32APIOptions.DEFAULT_OPTIONS);
// From https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-messagebox
int MB_OK = 0;
// The function to send the message
boolean WTSSendMessageW(HANDLE hServer, int SessionId,
LPWSTR pTitle, int TitleLength,
LPWSTR pMessage, int MessageLength,
int Style, int Timeout, IntByReference pResponse, boolean bWait);
boolean WTSQueryUserToken(long SessionId,HANDLE hServer);
}
Kernel32Ext.java
public interface Kernel32Ext extends Kernel32{
Kernel32Ext INSTANCE = Native.load("Kernel32",Kernel32Ext.class,W32APIOptions.DEFAULT_OPTIONS);
int WTSGetActiveConsoleSessionId();
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
当您的JNA功能映射不起作用时,第一个调试步骤应该是检查您的功能映射。
wtsqueryusertoken
定义为:Windows类型
ulong
is 一个无符号的32位整数;它应映射为int
,而不是long
。phandle
是指向handle>的指针
,而不是句柄本身。正确的JNA映射为handleByReference
。因此,您的接口函数映射应该是:
您要调用的代码应为:
When your JNA function mappings don't work, the first debugging step should be to check your function mappings.
WTSQueryUserToken
is defined as:The Windows type
ULONG
is an unsigned 32-bit integer; it should be mapped asint
, notlong
.PHANDLE
is a pointer to aHANDLE
, not the handle itself. The correct JNA mapping isHANDLEByReference
.So your interface function mapping should be:
And your code to call it should be: