【问题标题】:How to Detect workstation/System Screen Lock/unlock in windows OS using java?如何使用 java 在 Windows 操作系统中检测工作站/系统屏幕锁定/解锁?
【发布时间】:2023-03-08 20:40:01
【问题描述】:

我正在尝试记录在 Windows 操作系统中工作的每个员工的工作站/系统屏幕锁定和解锁。我需要使用 JAVA 将这些记录存储在数据库中。我已经到处搜索并了解如何使用 JAVA 进行操作。在我搜索过的地方,我只得到了 VB 的代码。

【问题讨论】:

  • 您找到解决方案了吗?我今天也有同样的需求...
  • @André 是的,但我们是使用 .Net 完成的;因为它在 java 中是一个漫长的过程,而且我们需要使用 JNI、C#、C++。这样我们就可以创建一个可以在我们的 java 代码中使用的 .dll 文件,这是一项艰巨的工作。所以我放弃了使用 Java 解决方案的想法。
  • @Andre 如果你想要 java 解决方案,请按照我接受的答案。

标签: java windows


【解决方案1】:

另一种方法,无需任何 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;

实际上,只有一种情况下锁识别不正确 - 当您拥有全黑的壁纸、隐藏的任务栏和隐藏的图标时。

【讨论】:

  • 我发现锁定的屏幕不是黑色的。另外,如果他们正在全屏观看电影并且它有一个完全黑框怎么办?
  • 您可以简单地使用 -16777216 而不是 Color.BLACK.getRGB() - 相同的值! :) - 顺便说一句:它对我来说就像一个魅力。
【解决方案2】:

您可以使用 JNA 在纯 Java 中完成此操作。将 jna.jarjna-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 中解决了这个问题。你可以在那里找到我自己的实现,但这里的代码要好得多!享受:)

【讨论】:

  • @Ladislav Gallay 我正在尝试您的上述实现,但我在 MainWindow 中有错误。它说不能解析为一种类型。我要为它导入什么(任何外部罐子)?
  • @Crawler 那将是 jna.jar 中的一个类。确保将两个 jna.jar 文件都添加到类路径中,然后您的 IDE 应该能够为您找到它。
  • @Crawler 啊抱歉,public WorkstationLockListening(MainWindow window) 中有未使用的属性。我已经编辑了我的答案并将其删除。这是我的自定义项目类,与此演示无关。
  • 这是我可以在网上找到的最简单、最干净的解决方案,用于使用 java 检测系统锁定和解锁。值得更多的支持:)
【解决方案3】:

使用 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

【讨论】:

  • 我已经浏览了您提供的那些链接,但我需要在纯 java 中完成。我知道在这种情况下没有使用 java 编码,因为插入了将 java 文件转换为头文件,最好用 C 或 C++ 本身或任何基于 Windows 的代码(如 VB 或任何基于 Windows 的代码)进行编码。?
  • 不幸的是,这个任务没有纯 Java 解决方案。唯一可能的方法是使用 Java + JNI + 调用系统 dll 文件。
  • 这可能工作过一次,但在 Windows 10 下不起作用。
【解决方案4】:

看看Unlock Administrator

该程序的目的是允许管理员分配可以解锁计算机的人员,但它也具有日志记录功能。它还允许您在计算机被锁定或解锁时运行脚本。这可能对您有帮助。

【讨论】:

  • 对不起。我正在寻找纯 java 的想法。
【解决方案5】:

使用 JDIC 库,

检查系统是否被锁定

SystemInfo.isSessionLocked()

【讨论】:

  • 我没有找到任何包含 JDIC 库的下载。如何使用它,在哪里可以找到它?
  • JDIC 是 java.net 项目。你可以在 repo 中找到免费的源代码。使用 ANT 自行下载和构建。一个月前我尝试了所有发行版并从互联网下载..
  • @Sathish 如果你没有找到罐子... ping me @ p.r.c.prabhu@gmail.com.. 发送给你。
【解决方案6】:

使用 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;
    }
});

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-01-24
    • 1970-01-01
    • 1970-01-01
    • 2011-01-27
    • 2012-03-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多