2023-02-17 438
我有一个应用程序,必须在退出时处理一些方法.但是,当用户关闭Windows而不首先关闭我的应用程序时,Windows杀死了该应用程序,而关闭方法未运行.
如何检测用户何时要求关闭Windows的注销或注销?我需要运行的方法以毫秒为单位完成,因此我不需要推迟或中断关闭过程.
我已经使用JNA来响应被锁定/解锁的机器,但是onMachineLogoff()方法似乎也没有捕获关闭请求.
有三种不同的方案和注销事件.我将重点关注Windows应用程序,因为它也适用于控制台应用程序,如果您的应用程序导入user32函数,则控制台句柄将不起作用.
基本上您需要2个功能:
ATOM RegisterClassEx(WNDCLASSEX *lpwcx);
与钩子(即我们的关闭/注销处理程序)创建一种新型的窗口.
HWND WINAPI CreateWindowEx(
int dwExStyle, LPCTSTR lpClassName, LPCTSTR lpWindowName,
int dwStyle, int x, int y, int nWidth, int nHeight,
HWND hWndParent, HMENU hMenu, HINSTANCE hInstance, LPVOID lpParam
);
实例化一个新窗口,此窗口具有关联的事件挂钩(通过注册类),此方式将Windows通知与所有可能的事件.
在这里,一个完整的工作示例,只需启动并注销或关闭计算机,然后启动它,请查看%userprofile%\shutdown-hook.log文件,它必须通过记录
之类的内容来处理这些事件
...
action=proc-callback, event=22
...
代码
public class Main {
/**
* <pre>
* Steps:
*
* 1. Create a WinProc (this function will handle all events)
* 2. Create a window class using the created WinProc
* 3. Create a window using the created window class
* 4. Use the WinProc to handle shutdown events
* </pre>
*/
public static void main(String[] args) {
// registering a window - https://msdn.microsoft.com/pt-br/library/windows/desktop/ms633587
// https://msdn.microsoft.com/pt-br/library/windows/desktop/ms633577
// typedef struct tagWNDCLASSEX {
// UINT cbSize;
// UINT style;
// WNDPROC lpfnWndProc;
// int cbClsExtra;
// int cbWndExtra;
// HINSTANCE hInstance;
// HICON hIcon;
// HCURSOR hCursor;
// HBRUSH hbrBackground;
// LPCTSTR lpszMenuName;
// LPCTSTR lpszClassName;
// HICON hIconSm;
// } WNDCLASSEX, *PWNDCLASSEX;
//
// ATOM WINAPI RegisterClassEx(
// _In_ const WNDCLASSEX *lpwcx
// );
final WinUser.WNDCLASSEX clazz = new WinUser.WNDCLASSEX();
clazz.lpszClassName = "MyCustomWindow";
clazz.cbSize = Native.getNativeSize(WinUser.WNDCLASSEX.class, null);
clazz.lpfnWndProc = new MyWinProc();
WinDef.ATOM classInst = User32.INSTANCE.RegisterClassEx(clazz);
System.out.printf("action=registerclass, clazz=%s, error=%d\n", classInst, Native.getLastError());
WinDef.HWND w = User32.INSTANCE.CreateWindowEx(
512, clazz.lpszClassName, "My Window",
WinUser.WS_OVERLAPPEDWINDOW, -2147483648, -2147483648, 250, 100,
null, null, null, null
);
System.out.printf("action=createWindow, w=%s, error=%d\n", w, Native.getLastError());
WinUser.MSG msg = new WinUser.MSG();
while (User32.INSTANCE.GetMessage(msg, null, 0, 0)) {
User32.INSTANCE.DispatchMessage(msg);
}
}
public interface User32 extends Library {
User32 INSTANCE = Native.loadLibrary("User32", User32.class, W32APIOptions.UNICODE_OPTIONS);
// ATOM WINAPI RegisterClassEx(
// _In_ const WNDCLASSEX *lpwcx
// );
WinDef.ATOM RegisterClassEx(WinUser.WNDCLASSEX lpwcx);
// HWND WINAPI CreateWindowEx(
// _In_ DWORD dwExStyle,
// _In_opt_ LPCTSTR lpClassName,
// _In_opt_ LPCTSTR lpWindowName,
// _In_ DWORD dwStyle,
// _In_ int x,
// _In_ int y,
// _In_ int nWidth,
// _In_ int nHeight,
// _In_opt_ HWND hWndParent,
// _In_opt_ HMENU hMenu,
// _In_opt_ HINSTANCE hInstance,
// _In_opt_ LPVOID lpParam
// );
WinDef.HWND CreateWindowEx(
int dwExStyle,
String lpClassName,
String lpWindowName,
int dwStyle,
int x,
int y,
int nWidth,
int nHeight,
WinDef.HWND hWndParent,
WinDef.HMENU hMenu,
WinDef.HINSTANCE hInstance,
WinDef.LPVOID lpParam
);
// BOOL WINAPI GetMessage(
// _Out_ LPMSG lpMsg,
// _In_opt_ HWND hWnd,
// _In_ UINT wMsgFilterMin,
// _In_ UINT wMsgFilterMax
// );
boolean GetMessage(WinUser.MSG lpMsg, WinDef.HWND hWnd, int wMsgFilterMin, int wMsgFilterMax);
// LRESULT WINAPI DispatchMessage(
// _In_ const MSG *lpmsg
// );
WinDef.LRESULT DispatchMessage(WinUser.MSG lpmsg);
WinDef.LRESULT DefWindowProc(WinDef.HWND hWnd, int uMsg, WinDef.WPARAM wParam, WinDef.LPARAM lParam);
}
/**
* <pre>
* All Possible events -
* https://msdn.microsoft.com/en-us/library/windows/desktop/ms644927.aspx#system_defined
* https://github.com/tpn/winsdk-10/blob/master/Include/10.0.10240.0/um/WinUser.h
* </pre>
*/
public static class MyWinProc implements WinUser.WindowProc {
private final OutputStream out;
public MyWinProc() {
try {
// this is unsafe because this file will never be closed, anyway it is just for a example
out = new FileOutputStream(new File(System.getProperty("user.home") + File.separator + "shutdown-hook.log"));
} catch (FileNotFoundException e) {
throw new RuntimeException(e);
}
}
@Override
public WinDef.LRESULT callback(WinDef.HWND hWnd, int uMsg, WinDef.WPARAM wParam, WinDef.LPARAM lParam) {
final String msg = String.format("action=proc-callback, event=%d %n", uMsg);
System.out.print(msg);
try {
out.write(msg.getBytes());
switch (uMsg){
case 0x0016:
out.write("shutdown".getBytes());
break;
case 0x0011:
out.write("logoff".getBytes());
break;
}
out.flush();
} catch (IOException e) {
throw new RuntimeException(e);
}
return User32.INSTANCE.DefWindowProc(hWnd, uMsg, wParam, lParam);
}
}
}
obs :只是一个建议,具体取决于您的要求,我认为如果您只是启动背景线程,并且按时间按时间来完成您必须执行的任务,那么可能会更有意义Windows获取死亡的蓝屏 或者,Power of Over of Over of Wo. Windows事件将无济于事.无论如何,背景线程解决方案更简单.
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
public class Main {
public static void main(String[] args) {
Executors.newSingleThreadExecutor().execute(() -> {
while(!Thread.currentThread().isInterrupted()){
System.out.println("do a background stuff");
try {
TimeUnit.SECONDS.sleep(10);
} catch (InterruptedException e) {/*I will look at that in the while clause*/}
}
});
System.out.println("doing another stuff");
}
}
我的依赖项
compile group: 'net.java.dev.jna', name: 'jna', version: '4.5.0'
compile group: 'net.java.dev.jna', name: 'jna-platform', version: '4.5.0'
以上所述是小编给大家介绍的JavaFX如何检测Windows注销/关闭请求?,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对77isp云服务器技术网的支持!
原文链接:https://77isp.com/post/34139.html
=========================================
https://77isp.com/ 为 “云服务器技术网” 唯一官方服务平台,请勿相信其他任何渠道。
数据库技术 2022-03-28
网站技术 2022-11-26
网站技术 2023-01-07
网站技术 2022-11-17
Windows相关 2022-02-23
网站技术 2023-01-14
Windows相关 2022-02-16
Windows相关 2022-02-16
Linux相关 2022-02-27
数据库技术 2022-02-20
抠敌 2023年10月23日
嚼餐 2023年10月23日
男忌 2023年10月22日
瓮仆 2023年10月22日
簿偌 2023年10月22日
扫码二维码
获取最新动态