我试图记下在 Windows 操作系统中工作的每个员工的工作站/系统屏幕锁定和解锁。我需要使用 JAVA 将这些记录存储在数据库中。我已经到处搜索并了解如何使用 JAVA 进行操作。在我搜索过的地方,我只得到了 VB 的代码。
6 回答
您可以使用JNA在纯 Java 中执行此操作。将jna.jar和jna -platform.jar添加到您的项目中。在这个文件com.sun.jna.platform.win32.Win32WindowDemo中有一个锁定和解锁监听器的完整示例等等。这是来自 Win32WindowDemo 的必要代码:
public class WorkstationLockListening implements WindowProc
{
/**
* Instantiates a new win32 window test.
*/
public WorkstationLockListening()
{
// define new window class
final WString windowClass = new WString("MyWindowClass");
final HMODULE hInst = Kernel32.INSTANCE.GetModuleHandle("");
WNDCLASSEX wClass = new WNDCLASSEX();
wClass.hInstance = hInst;
wClass.lpfnWndProc = WorkstationLockListening.this;
wClass.lpszClassName = windowClass;
// register window class
User32.INSTANCE.RegisterClassEx(wClass);
getLastError();
// create new window
final HWND hWnd = User32.INSTANCE.CreateWindowEx(User32.WS_EX_TOPMOST, windowClass, "'TimeTracker hidden helper window to catch Windows events", 0, 0, 0, 0, 0, null, // WM_DEVICECHANGE contradicts parent=WinUser.HWND_MESSAGE
null, hInst, null);
getLastError();
System.out.println("window sucessfully created! window hwnd: " + hWnd.getPointer().toString());
Wtsapi32.INSTANCE.WTSRegisterSessionNotification(hWnd, Wtsapi32.NOTIFY_FOR_THIS_SESSION);
MSG msg = new MSG();
while (User32.INSTANCE.GetMessage(msg, hWnd, 0, 0) != 0)
{
User32.INSTANCE.TranslateMessage(msg);
User32.INSTANCE.DispatchMessage(msg);
}
/// This code is to clean at the end. You can attach it to your custom application shutdown listener
Wtsapi32.INSTANCE.WTSUnRegisterSessionNotification(hWnd);
User32.INSTANCE.UnregisterClass(windowClass, hInst);
User32.INSTANCE.DestroyWindow(hWnd);
System.out.println("program exit!");
}
/*
* (non-Javadoc)
*
* @see com.sun.jna.platform.win32.User32.WindowProc#callback(com.sun.jna.platform .win32.WinDef.HWND, int, com.sun.jna.platform.win32.WinDef.WPARAM, com.sun.jna.platform.win32.WinDef.LPARAM)
*/
public LRESULT callback(HWND hwnd, int uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
case WinUser.WM_DESTROY:
{
User32.INSTANCE.PostQuitMessage(0);
return new LRESULT(0);
}
case WinUser.WM_SESSION_CHANGE:
{
this.onSessionChange(wParam, lParam);
return new LRESULT(0);
}
default:
return User32.INSTANCE.DefWindowProc(hwnd, uMsg, wParam, lParam);
}
}
/**
* Gets the last error.
*
* @return the last error
*/
public int getLastError()
{
int rc = Kernel32.INSTANCE.GetLastError();
if (rc != 0)
System.out.println("error: " + rc);
return rc;
}
/**
* On session change.
*
* @param wParam
* the w param
* @param lParam
* the l param
*/
protected void onSessionChange(WPARAM wParam, LPARAM lParam)
{
switch (wParam.intValue())
{
case Wtsapi32.WTS_SESSION_LOCK:
{
this.onMachineLocked(lParam.intValue());
break;
}
case Wtsapi32.WTS_SESSION_UNLOCK:
{
this.onMachineUnlocked(lParam.intValue());
break;
}
}
}
/**
* On machine locked.
*
* @param sessionId
* the session id
*/
protected void onMachineLocked(int sessionId)
{
System.out.println("Machine locked right now!");
}
/**
* On machine unlocked.
*
* @param sessionId
* the session id
*/
protected void onMachineUnlocked(int sessionId)
{
System.out.println("Machine unlocked right now!");
}
}
我们已经在Google Group Workstation Lock/Unlock listener中解决了这个问题。你可以在那里找到我自己的实现,但这里的代码要好得多!享受 :)
另一种方法,没有任何 Windows 系统库等。
主要思想 - 锁定 PC 的屏幕截图将是全黑的,因此您可以截取一张并简单地检查一些关键点是否为黑色
-16777216 - 幻数,表示 FFFFFFFFFF000000xH,最后一个 00 00 00 表示 RGB 颜色代码(实际上是黑色)
BufferedImage image = new Robot().createScreenCapture(new Rectangle(Toolkit.getDefaultToolkit().getScreenSize()));
boolean isBlack;
isBlack = (image.getRGB(1,1)==-16777216)
&(image.getRGB(1,image.getHeight()-1)==-16777216)
&(image.getRGB(image.getWidth()-1,1)==-16777216)
&(image.getRGB(image.getWidth()-1,image.getHeight()-1)==-16777216)
&(image.getRGB(image.getWidth()/2,image.getHeight()/2)==-16777216);
return isBlack;
实际上,只有一种情况下锁识别不正确 - 当您拥有全黑的壁纸、隐藏的任务栏和隐藏的图标时。
使用 JNI (Java Native Interface) 从 Windows 系统 dll 调用函数。
以下是使用检查工作站锁定状态的函数的示例代码:http: //brutaldev.com/post/2008/05/23/Checking-if-the-workstation-is-locked.aspx
这里是关于通过 JNI 从 Java 调用 dll 函数的文章:http: //edn.embarcadero.com/article/20679
看看解锁管理员
该程序的目的是允许管理员分配谁可以解锁计算机,但它也具有日志记录功能。它还允许您在计算机被锁定或解锁时运行脚本。这可能对您有帮助。
使用 JDIC 库,
检查系统是否锁定
SystemInfo.isSessionLocked()
使用 JDK9 (JDK11),您可以使用 java.awt.Desktop :
Desktop tempDesktop = Desktop.getDesktop();
tempDesktop.addAppEventListener(new UserSessionListener() {
@Override
public void userSessionDeactivated(UserSessionEvent aE) {
LOG.info("Desktop:userSessionDeactivated Reason=" + aE.getReason() + " Source=" + aE.getSource());
// Windows Key L:
// Tue Aug 31 11:22:49 CEST 2021:info:MainController:userSessionDeactivated Reason=LOCK
// Close Lid:
// Tue Aug 31 11:24:38 CEST 021:info:MainController:userSessionDeactivated Reason=LOCK
// Tue Aug 31 11:24:39 CEST 2021:info:MainController:systemAboutToSleep Source=java.awt.Desktop@741f67cd
ptcUserStatus = PtcUserStatus.AWAY;
}
@Override
public void userSessionActivated(UserSessionEvent aE) {
LOG.info("Desktop:userSessionActivated Reason=" + aE.getReason() + " Source=" + aE.getSource());
// Logon after Windows Key L
// Tue Aug 31 11:22:53 CEST 2021:info:MainController:userSessionActivated Reason=LOCK
// Open Lid:
// Tue Aug 31 11:24:56 CEST 2021:info:MainController:systemAwoke Source=java.awt.Desktop@741f67cd
// Tue Aug 31 11:25:06 CEST 2021:info:MainController:userSessionActivated Reason=LOCK
ptcUserStatus = PtcUserStatus.BACK;
}
});