如何使用wtssendmessage显示消息?

发布于 2025-01-21 14:54:21 字数 800 浏览 5 评论 0 原文

完成任务后,我想向用户显示一些消息。但是该应用程序是作为服务运行的,因此无法使用UI组件。

Microsoft文档说我们可以使用Win32 API: wtssendmessage 显示对话框。我浏览了JNA文档,但找不到此特定内容的任何参考。我想为Java应用程序这样做。有办法通过JNA吗?

链接到WTSSENDMESSAGEA的文档:

这是Microsoft:Microsoft:

I want to display some message to the user when a task is completed. But the Application is running as a service, so it's not possible to use a UI component.

Microsoft documentation says we can use win32 API: WTSSendMessage to show a dialog box. I went through the JNA documentation but couldn't find any reference for this specific thing. I want to do this for a Java application. Is there a way through JNA?

Link to the documentation of WTSSendMessageA: https://learn.microsoft.com/en-us/windows/win32/api/wtsapi32/nf-wtsapi32-wtssendmessagea

Here are some other ways suggested by Microsoft:
https://learn.microsoft.com/en-us/windows/win32/services/interactive-services?redirectedfrom=MSDN

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

天涯沦落人 2025-01-28 14:54:21

根据您提供的链接 ,服务可以

使用 wtssendmessage 函数在用户会话中显示一个对话框。

JNA由 JNA 伪像的基本功能和 jna-platform trafact中的用户分配的映射组成。尽管JNA中存在 WTSAPI32 类,但只有某些DLL的功能已映射,但 WTSSENDMESSAGE 均未映射。

我注意到您将文档链接到-A后缀版本:这是不适用于任何现代版本Windows的“ ANSI”映射。如果您使用Winapi默认类型映射器映射非填充版本,它将自动选择正确的-a或-w后缀版本(区别在于-w使用UTF16宽字符串,而-a使用8位ASCII)。但是为了方便起见,您只需映射-w版本, wtssendmessagew

看一下参数列表,您需要:

  • handle wtsopenserver 发送
  • 到的会话(您可以使用当前会话)
  • 您可以创建一个标题bar
  • 字符串消息您可以创建
  • 样式(您只需使用“ OK”版本)
  • 超时指针
  • 以接收服务器句柄的响应值

wtsopenserver 状态

您无需打开在应用程序正在运行的RD会话主机服务器上执行的操作的手柄。使用常数 wts_current_server_handle 代替。

这已经在JNA中映射(这是 handle 包装null)。

因此,您只需要映射 wtssendmessage 函数即可。类型映射很简单。 处理 lpwstr 在JNA中映射,您应该使用 int dword args和 boolean bool 。您将使用接口,并扩展现有的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://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);
}

然后使用功能。我们可以使用当前的服务器句柄,当前会话,创建我们的字符串传递,使用“确定”样式,并通过将false作为等待参数来忽略超时/响应。

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()

这都是未经测试的。您需要适当的进口。

According to the link you provided, a service can

Display a dialog box in the user's session using the WTSSendMessage function.

JNA is comprised of the base functionality in the jna artifact and user-contributed mappings in the jna-platform artifact. While the Wtsapi32 class exists in JNA, only some of that dll's functions have been mapped, but not WTSSendMessage.

I note you linked the docs to the -A suffixed version: this is the "ANSI" mapping that does not apply to any modern version of windows. If you map the un-suffixed version using the WinAPI default type mapper, it will automatically choose the correct -A or -W suffixed version (the difference is that -W uses UTF16 wide strings while -A uses 8-bit ASCII). But for your convenience you can just map the -W version, WTSSendMessageW.

Looking down the list of arguments, you need:

  • A HANDLE obtained from WTSOpenServer
  • The session to send to (you can use the current session)
  • A title bar string you can create
  • A message you can create
  • A style (you can just use the "OK" version)
  • A timeout
  • A pointer to receive the response value

For the server handle, the docs for 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.

This is already mapped in JNA (it's a HANDLE wrapping null).

So you just need to map the WTSSendMessage function. The type mappings are straightforward. HANDLE and LPWSTR are mapped in JNA, and you should use int for the DWORD args and boolean for BOOL. You'll use an interface, and extend the existing JNA mapping to obtain access to its functions:

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://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);
}

Then use the functions. We can use the current server handle, the current session, create our strings to pass, use the "OK" style, and ignore the timeout/response by passing false as the wait parameter.

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()

This is all untested. You'll need appropriate imports.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文