简体   繁体   English

如何使用 java 在 Windows 操作系统中检测工作站/系统屏幕锁定/解锁?

[英]How to Detect workstation/System Screen Lock/unlock in windows OS using java?

I'm trying to note down workstation/System screen Lock and Unlock of each employee working in windows OS.我试图记下每个在 Windows 操作系统中工作的员工的工作站/系统屏幕锁定和解锁。 I needed to store these record in a DataBase, using JAVA.我需要使用 JAVA 将这些记录存储在数据库中。 I have searched all over and got on idea how to do it using JAVA.我已经到处搜索并开始了解如何使用 JAVA 来完成它。 where ever I searched I get code for VB only.我搜索过的地方只得到 VB 的代码。

You can do it in pure Java using JNA .您可以使用JNA在纯 Java 中完成。 Add jna.jar and jna-platform.jar to your project.jna.jarjna -platform.jar添加到您的项目中。 And in this file com.sun.jna.platform.win32.Win32WindowDemo there is a full example of lock and unlock listener and much more.在这个文件com.sun.jna.platform.win32.Win32WindowDemo 中有一个完整的锁定和解锁监听器示例等等。 Here is the necessary code from thah 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!");
    }
}

We have solved this problem in Google Group Workstation Lock / Unlock listener .我们已经在Google Group Workstation Lock / Unlock listener 中解决了这个问题。 You can find there my own implementation but this code right here is much better!你可以在那里找到我自己的实现,但这里的代码要好得多! Enjoy :)享受 :)

One more way, without any windows system libs, ect.另一种方式,没有任何 Windows 系统库,等等。

Main idea - screenshots for locked PC will be totally black, so you can take one and simply check that some critical points are black主要思想 - 锁定 PC 的屏幕截图将是全黑的,因此您可以截取一张并简单地检查某些关键点是否为黑色

-16777216 - magic number, that means FFFFFFFFFF000000xH and last 00 00 00 means RGB color code (actually black color) -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;

Actually, there could be only one case with incorrect lock identification - when you have totally black wallpaper, with hidden taskbar and hidden icons.实际上,可能只有一种情况下锁定标识不正确 - 当您拥有全黑墙纸、隐藏的任务栏和隐藏的图标时。

Use JNI (Java Native Interface) to invoke functions from the Windows system dll.使用 JNI(Java Native Interface)从 Windows 系统 dll 调用函数。

Here is the sample code for use of functions which check workstation locking state: http://brutaldev.com/post/2008/05/23/Checking-if-the-workstation-is-locked.aspx以下是使用检查工作站锁定状态的函数的示例代码: http : //brutaldev.com/post/2008/05/23/Checking-if-the-workstation-is-locked.aspx

And here is the article about invoking dll-functions from Java via JNI: http://edn.embarcadero.com/article/20679这是关于通过 JNI 从 Java 调用 dll 函数的文章: http : //edn.embarcadero.com/article/20679

Have a look at Unlock Administrator看看解锁管理员

The purpose of the program is allow the admin at assign who can unlock the computer but it also has logging capability.该程序的目的是允许管理员分配谁可以解锁计算机,但它也具有日志记录功能。 It also allows you to run a script whenever the computer is locked or unlocked.它还允许您在计算机锁定或解锁时运行脚本。 This may be helpful to you.这可能对您有所帮助。

Using JDIC Library,使用 JDIC 库,

To Check the system is Locked or Not检查系统是否锁定

SystemInfo.isSessionLocked() SystemInfo.isSessionLocked()

With JDK9 (JDK11) you can use java.awt.Desktop :使用 JDK9 (JDK11),您可以使用 java.awt.Desktop :

Desktop tempDesktop = Desktop.getDesktop();桌面 tempDesktop = Desktop.getDesktop(); tempDesktop.addAppEventListener(new UserSessionListener() { 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 2021: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;
        }
    });

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM