如何使用 WTSSendMessage 显示消息?
How to display message using WTSSendMessage?
我想在任务完成时向用户显示一些消息。但是该应用程序是 运行 作为一项服务,因此无法使用 UI 组件。
Microsoft 文档说我们可以使用 win32 API: WTSSendMessage
来显示对话框。我浏览了 JNA 文档,但找不到关于这个特定内容的任何参考。我想为 Java 应用程序执行此操作。有办法通过JNA吗?
Link 到 WTSSendMessageA 的文档:https://docs.microsoft.com/en-us/windows/win32/api/wtsapi32/nf-wtsapi32-wtssendmessagea
以下是 Microsoft 建议的其他一些方法:
https://docs.microsoft.com/en-us/windows/win32/services/interactive-services?redirectedfrom=MSDN
根据the link you provided,服务可以
Display a dialog box in the user's session using the WTSSendMessage
function.
JNA 由 jna
工件中的基本功能和 jna-platform
工件中的 user-contributed 映射组成。虽然 Wtsapi32
class 存在于 JNA 中,但仅映射了该 dll 的一些函数,但未映射 WTSSendMessage
.
我注意到您将文档链接到后缀为 -A 的版本:这是不适用于 windows 的任何现代版本的“ANSI”映射。如果使用 WinAPI 默认类型映射器映射 un-suffixed 版本,它将自动选择正确的 -A 或 -W 后缀版本(不同之处在于 -W 使用 UTF16 宽字符串,而 -A 使用 8 位 ASCII) .但为了您的方便,您可以只映射 -W 版本,WTSSendMessageW
.
查看参数列表,您需要:
- 从
WTSOpenServer
获得的HANDLE
- 发送至session(可以使用当前的session)
- 您可以创建的标题栏字符串
- 您可以创建的消息
- 一种风格(你可以使用“OK”版本)
- 超时
- 接收响应值的指针
对于服务器句柄,WTSOpenServer
state
的文档
You do not need to open a handle for operations performed on the RD Session Host server on which your application is running. Use the constant WTS_CURRENT_SERVER_HANDLE
instead.
这已经在 JNA 中映射(它是一个 HANDLE
包装 null)。
所以你只需要映射WTSSendMessage
函数。类型映射很简单。 HANDLE
和 LPWSTR
在 JNA 中映射,您应该对 DWORD
args 使用 int
,对 BOOL
使用 boolean
。您将使用一个接口,并扩展现有的 JNA 映射以获得对其功能的访问:
public interface MyWtsapi32 extends com.sun.jna.platform.win32.Wtsapi32 {
// Your own instance to access your functions
MyWtsapi32 INSTANCE = Native.load("Wtsapi32", Wtsapi32.class, W32APIOptions.DEFAULT_OPTIONS);
// From https://docs.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);
}
然后使用函数。我们可以使用当前服务器句柄,当前 session,创建要传递的字符串,使用“OK”样式,并通过传递 false 作为等待参数来忽略 timeout/response。
LPWSTR pTitle = new LPWSTR("Message box title");
int titleLength = ("Message box title".length() + 1) * Native.WCHAR_SIZE;
LPWSTR pMessage = new LPWSTR("Hello World!");
int messageLength = ("Hello World!".length() + 1) * Native.WCHAR_SIZE;
IntByReference pResponse = new IntByReference();
MyWtsapi32.INSTANCE.WTSSendMessageW(
WTS_CURRENT_SERVER_HANDLE, WTS_CURRENT_SESSION,
pTitle, titleLength,
pMessage, messageLength,
MB_OK, 0, pResponse, false);
// should return IDASYNC in pResponse.getValue()
这一切都未经测试。您需要适当的导入。
我想在任务完成时向用户显示一些消息。但是该应用程序是 运行 作为一项服务,因此无法使用 UI 组件。
Microsoft 文档说我们可以使用 win32 API: WTSSendMessage
来显示对话框。我浏览了 JNA 文档,但找不到关于这个特定内容的任何参考。我想为 Java 应用程序执行此操作。有办法通过JNA吗?
Link 到 WTSSendMessageA 的文档:https://docs.microsoft.com/en-us/windows/win32/api/wtsapi32/nf-wtsapi32-wtssendmessagea
以下是 Microsoft 建议的其他一些方法: https://docs.microsoft.com/en-us/windows/win32/services/interactive-services?redirectedfrom=MSDN
根据the link you provided,服务可以
Display a dialog box in the user's session using the
WTSSendMessage
function.
JNA 由 jna
工件中的基本功能和 jna-platform
工件中的 user-contributed 映射组成。虽然 Wtsapi32
class 存在于 JNA 中,但仅映射了该 dll 的一些函数,但未映射 WTSSendMessage
.
我注意到您将文档链接到后缀为 -A 的版本:这是不适用于 windows 的任何现代版本的“ANSI”映射。如果使用 WinAPI 默认类型映射器映射 un-suffixed 版本,它将自动选择正确的 -A 或 -W 后缀版本(不同之处在于 -W 使用 UTF16 宽字符串,而 -A 使用 8 位 ASCII) .但为了您的方便,您可以只映射 -W 版本,WTSSendMessageW
.
查看参数列表,您需要:
- 从
WTSOpenServer
获得的 - 发送至session(可以使用当前的session)
- 您可以创建的标题栏字符串
- 您可以创建的消息
- 一种风格(你可以使用“OK”版本)
- 超时
- 接收响应值的指针
HANDLE
对于服务器句柄,WTSOpenServer
state
You do not need to open a handle for operations performed on the RD Session Host server on which your application is running. Use the constant
WTS_CURRENT_SERVER_HANDLE
instead.
这已经在 JNA 中映射(它是一个 HANDLE
包装 null)。
所以你只需要映射WTSSendMessage
函数。类型映射很简单。 HANDLE
和 LPWSTR
在 JNA 中映射,您应该对 DWORD
args 使用 int
,对 BOOL
使用 boolean
。您将使用一个接口,并扩展现有的 JNA 映射以获得对其功能的访问:
public interface MyWtsapi32 extends com.sun.jna.platform.win32.Wtsapi32 {
// Your own instance to access your functions
MyWtsapi32 INSTANCE = Native.load("Wtsapi32", Wtsapi32.class, W32APIOptions.DEFAULT_OPTIONS);
// From https://docs.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);
}
然后使用函数。我们可以使用当前服务器句柄,当前 session,创建要传递的字符串,使用“OK”样式,并通过传递 false 作为等待参数来忽略 timeout/response。
LPWSTR pTitle = new LPWSTR("Message box title");
int titleLength = ("Message box title".length() + 1) * Native.WCHAR_SIZE;
LPWSTR pMessage = new LPWSTR("Hello World!");
int messageLength = ("Hello World!".length() + 1) * Native.WCHAR_SIZE;
IntByReference pResponse = new IntByReference();
MyWtsapi32.INSTANCE.WTSSendMessageW(
WTS_CURRENT_SERVER_HANDLE, WTS_CURRENT_SESSION,
pTitle, titleLength,
pMessage, messageLength,
MB_OK, 0, pResponse, false);
// should return IDASYNC in pResponse.getValue()
这一切都未经测试。您需要适当的导入。