📄 win32sessionmanager.java
字号:
package org.xvolks.jnative.util.win32session;
import java.awt.Dialog;
import java.awt.Frame;
import java.awt.TextField;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import org.xvolks.jnative.JNative;
import org.xvolks.jnative.exceptions.NativeException;
import org.xvolks.jnative.misc.MSG;
import org.xvolks.jnative.misc.MSG.WindowsConstants;
import org.xvolks.jnative.misc.basicStructures.HWND;
import org.xvolks.jnative.misc.basicStructures.LPARAM;
import org.xvolks.jnative.misc.basicStructures.LRESULT;
import org.xvolks.jnative.misc.basicStructures.UINT;
import org.xvolks.jnative.misc.basicStructures.WPARAM;
import org.xvolks.jnative.util.Callback;
import org.xvolks.jnative.util.Kernel32;
import org.xvolks.jnative.util.User32;
import org.xvolks.jnative.util.WindowProc;
import org.xvolks.jnative.util.constants.winuser.WM;
/**
*
*/
/**
* @author Marc DENTY (mdt) - 14 nov. 06 $Id: Win32SessionManager.java,v 1.4 2007/04/25 11:46:54 thubby Exp $
*
*/
public class Win32SessionManager {
public interface EndSessionListener {
public enum Origin {
CONSOLE,
WINDOW,
;
}
/**
* Called when a EndSession event is detected
* @param org
* @return true to let the session to close, false to stop that process
*/
public boolean queryEndSessionOccured(Origin org);
/**
* This event is only avaliable if launched with javaw.exe (windows)
* @param org
*/
public void endSessionOccured(Origin org);
/**
* This event is only avaliable if launched with java.exe (console)
* @param org
*/
public void shutdownOccured(Origin org);
}
private static final CallBackWindowProc console_proc = new CallBackWindowProc();
private static List<EndSessionListener> listeners = new ArrayList<EndSessionListener>();
public static void addEndSessionListener(EndSessionListener listener) {
if(!listeners.contains(listener)){
listeners.add(listener);
}
}
public static boolean removeEndSessionListener(EndSessionListener listener) {
return listeners.remove(listener);
}
public static boolean fireQueryEndSessionOccured(EndSessionListener.Origin origin) {
boolean ret = true;
for(EndSessionListener l : listeners) {
ret &= l.queryEndSessionOccured(origin);
}
return ret;
}
public static void fireEndSessionOccured(EndSessionListener.Origin origin) {
for(EndSessionListener l : listeners) {
l.endSessionOccured(origin);
}
}
public static void fireShutdownOccured(EndSessionListener.Origin origin) {
for(EndSessionListener l : listeners) {
l.shutdownOccured(origin);
}
}
static class CallBackWindowProc implements Callback {
public int HandlerRoutine(int msg) {
switch (msg) {
/*
* CTRL_C_EVENT 0 A CTRL+C signal was received, either from
* keyboard input or from a signal generated by the
* GenerateConsoleCtrlEvent function. CTRL_BREAK_EVENT 1 A
* CTRL+BREAK signal was received, either from keyboard input or
* from a signal generated by GenerateConsoleCtrlEvent.
* CTRL_CLOSE_EVENT 2 A signal that the system sends to all
* processes attached to a console when the user closes the
* console (either by clicking Close on the console window's
* window menu, or by clicking the End Task button command from
* Task Manager). CTRL_LOGOFF_EVENT 5 A signal that the system
* sends to all console processes when a user is logging off.
* This signal does not indicate which user is logging off, so
* no assumptions can be made.
*
* Note that this signal is received only by services.
* Interactive applications are terminated at logoff, so they
* are not present when the system sends this signal.
* CTRL_SHUTDOWN_EVENT 6 A signal that the system sends when the
* system is shutting down. Interactive applications are not
* present by the time the system sends this signal, therefore
* it can be received only be services in this situation.
* Services also have their own notification mechanism for
* shutdown events. For more information, see Handler.
*/
case 5:
return fireQueryEndSessionOccured(EndSessionListener.Origin.CONSOLE) ? 0 : 1;
case 6:
fireShutdownOccured(EndSessionListener.Origin.CONSOLE);
break;
default:
}
return 1;
}
public int callback(long[] values) {
return HandlerRoutine(
(int) values[0]);
}
private int instance=0;
public int getCallbackAddress() throws NativeException {
if (instance==0) {
instance=JNative.createCallback(1, this);
}
return instance;
}
public boolean releaseCallbackAddress() throws NativeException {
if(instance != 0 && JNative.releaseCallback(this)) {
instance = 0;
return true;
} else {
return false;
}
}
}
private static HWND _hwnd = null;
private static int oldWindowProc;
/**
*
* @throws NativeException
* @throws IllegalAccessException
*/
public static boolean unregisterEndSessionHook() throws NativeException, IllegalAccessException {
boolean ret = Kernel32.SetConsoleCtrlHandler(console_proc, false);
if(JNative.isLogginEnabled())
System.err.println("RemoveConsoleHandler : " + ret);
if(ret) {
console_proc.releaseCallbackAddress();
}
if(oldWindowProc != 0) {
LRESULT result = User32.SendMessage(_hwnd, new UINT(WM.WM_CLOSE.getValue()), new WPARAM(0), new LPARAM(0));
if(JNative.isLogginEnabled()) {
System.err.println("SendMessage WM_CLOSE returned " + result.getValue());
}
ret &= result.getValue() == 0;
}
return ret;
}
/**
* Be aware that calling this method <i>eats</i> one callback and the registerWindowProc slot !<br>
* This also prevents the app to close.
*
* @throws IllegalAccessException
* @throws NativeException
*/
public static void registerEndSessionHook(final String windowName) throws NativeException, IllegalAccessException {
if(JNative.isLogginEnabled())
System.err.println("SetConsoleHandler : " + Kernel32.SetConsoleCtrlHandler(console_proc, true));
else
Kernel32.SetConsoleCtrlHandler(console_proc, true);
new Thread() {
{
setDaemon(true);
setName("EndSessionListener");
}
public void run() {
WindowProc proc = new WindowProc() {
public int windowProc(int hwnd, int uMsg, int wParam, int lParam) {
writeLog("log "+uMsg);
if (_hwnd != null || hwnd == _hwnd.getValue()) {
if(uMsg == WM.WM_QUERYENDSESSION.getValue()) {
return fireQueryEndSessionOccured(EndSessionListener.Origin.WINDOW) ? -1 : 0;
} else if(uMsg == WM.WM_ENDSESSION.getValue()) {
fireEndSessionOccured(EndSessionListener.Origin.WINDOW);
return -1;
} else {
try {
int ret = User32.DefWindowProc(new HWND(hwnd), new UINT(uMsg), new WPARAM(wParam),
new LPARAM(lParam)).getValue();
return ret;
} catch (Exception ex) {
return 0;
}
}
} else {
System.err.println("Je ne gere pas 鏰 !");
return -1;
}
}
};
try {
// Pointer p = new
// Pointer(MemoryBlockFactory.createMemoryBlock(20));
// p.setStringAt(0, "Invisible");
_hwnd = new HWND(User32.CreateWindowEx(0,
"Message", windowName==null?"":windowName, 0, 0, 0, 100, 100, 0, 0, JNative.getCurrentModule(), 0));
if(0==_hwnd.getValue()) {
System.err.println("Failed to create the message listener window");
}
} catch (Exception ex) {
ex.printStackTrace();
System.err.println("Can't create the message listener window.");
}
try {
oldWindowProc = JNative.registerWindowProc(_hwnd, proc);
// User32.SetWindowLong(_hwnd, WindowsConstants.GWL_WNDPROC, new
// LONG(test));
} catch (Exception e1) {
e1.printStackTrace();
}
try {
User32.ShowWindow(_hwnd, WindowsConstants.SW_HIDE);
User32.UpdateWindow(_hwnd);
} catch (Exception e) {
e.printStackTrace();
}
MSG msg = null;
try {
msg = new MSG();
} catch (NativeException e) {
e.printStackTrace();
}
boolean lQuit = false;
try {
while (!lQuit) {
switch (User32.GetMessage(msg, new HWND(0), 0, 0)) {
case -1:
int error = Kernel32.getLastError();
System.err.println("Error occured: " + error);
lQuit = true;
break;
case 0:
System.err.println("WM_QUIT received");
lQuit = true;
break;
}
User32.TranslateMessage(msg);
User32.DispatchMessage(msg);
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
}.start();
}
private static PrintWriter log=null;
private static FileOutputStream fLog=null;
public static void writeLog(String message) {
if (fLog==null) {
try {
fLog=new FileOutputStream("./Win32SessionManager.log");
log=new PrintWriter(fLog);
Runtime.getRuntime().addShutdownHook(new Thread() {
public void run() {
writeLog("Closing log");
log.close();
}
});
} catch (Exception e) {
return;
}
}
log.println("["+new Date()+"] "+message);
log.flush();
try {
fLog.getChannel().force(false);
} catch (IOException e) {
}
}
public static void main(String[] args) throws NativeException, IllegalAccessException {
writeLog("Running");
addEndSessionListener(new EndSessionListener() {
public void endSessionOccured(Origin org) {
writeLog("Fin de session par "+org);
}
public boolean queryEndSessionOccured(Origin org) {
writeLog("Demande de fin de session par "+org);
return true;
}
public void shutdownOccured(Origin org) {
writeLog("Shutdown captured from "+org);
}
});
writeLog("Registring hook");
registerEndSessionHook("Noone");
final Dialog d = new Dialog(new Frame());
d.setModal(true);
d.add(new TextField("Testing, please close session"));
d.pack();
d.addWindowListener(new WindowAdapter() {
/* (non-Javadoc)
* @see java.awt.event.WindowAdapter#windowClosing(java.awt.event.WindowEvent)
*/
@Override
public void windowClosing(WindowEvent e) {
d.dispose();
}
});
d.setVisible(true);
writeLog("Exiting");
System.exit(0);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -