使用Java JNA捕获Win32事件

使用Java JNA捕获Win32事件,java,winapi,jna,Java,Winapi,Jna,我正在解决这个问题: 在安装在Windows OS机器上的Java应用程序中,我必须捕获由同一机器上的另一个应用程序创建的Win32事件。这个应用程序是用C++编写的,没有办法改变它。我有我必须使用OpenEvent函数的信息。我从以下内容开始: 这是我的密码: public class WinEventListener { private Logger logger = LoggerFactory.getLogger(WinEventListener.class);

我正在解决这个问题:

在安装在Windows OS机器上的Java应用程序中,我必须捕获由同一机器上的另一个应用程序创建的Win32事件。这个应用程序是用C++编写的,没有办法改变它。我有我必须使用OpenEvent函数的信息。我从以下内容开始:

这是我的密码:

    public class WinEventListener {
    private Logger logger = LoggerFactory.getLogger(WinEventListener.class);

    static {
        Native.register("kernel32");
    }

    public static native HANDLE OpenEventW(int access, boolean inheritHandle, WString name);

    public static native int WaitForSingleObject(HANDLE hHandle, int dwMilliseconds);

    public static native boolean CloseHandle(HANDLE hObject);

    public static class HANDLE extends PointerType {

        public Object fromNative(Object nativeValue, FromNativeContext context) {
            Object o = super.fromNative(nativeValue, context);
            if (INVALID_HANDLE_VALUE.equals(o))
                return INVALID_HANDLE_VALUE;
            return o;
        }
    }

    static HANDLE INVALID_HANDLE_VALUE = new HANDLE() {

        {
            super.setPointer(Pointer.createConstant(-1));
        }

        public void setPointer(Pointer p) {
            throw new UnsupportedOperationException("Immutable reference");
        }
    };

    public void listen() throws Exception {
        HANDLE handle = null;
        do {
            //logger.debug("Wainting for handle");
            handle = OpenEventW(2, false, new WString("VLIT_SERVER_DATA"));
            logger.debug("Handle:" + handle.toString());
            Thread.sleep(1000);
        } while (handle == null);
        logger.debug("Handle obtained");

        while(true){
            int result = WaitForSingleObject(handle,Integer.MAX_VALUE);
            if(result == 0){
                logger.debug("Handle signalized");
                VLITProcceserThread thread = new VLITProcceserThread();
                thread.start();
                CloseHandle(handle);
            }
        }

    }


}
基本上,我希望在listen方法中等待由其他程序创建的句柄,如果它已创建,则等待其信号状态,执行一些操作并释放句柄

但我没有成功。有人能给我指出正确的方向吗


太多了

如果句柄打开失败,则很可能是权限问题。您的程序是否作为服务运行?我试图做一些类似的事情,当我在一个作为服务运行的程序中通过系统调用调用它时,我能够让这个程序运行并工作

import com.sun.jna.Native;
import com.sun.jna.Pointer;
import com.sun.jna.PointerType;
import com.sun.jna.WString;
import com.sun.jna.FromNativeContext;

public class WinEventListener {
    static {
        Native.register("kernel32");
    }

public static native HANDLE OpenEventW(int access, boolean inheritHandle, WString name);

public static native int WaitForSingleObject(HANDLE hHandle, int dwMilliseconds);

public static native boolean CloseHandle(HANDLE hObject);

public static class HANDLE extends PointerType {

    public Object fromNative(Object nativeValue, FromNativeContext context) {
        Object o = super.fromNative(nativeValue, context);
        if (INVALID_HANDLE_VALUE.equals(o))
            return INVALID_HANDLE_VALUE;
        return o;
    }
}

static HANDLE INVALID_HANDLE_VALUE = new HANDLE() {

    {
        super.setPointer(Pointer.createConstant(-1));
    }

    public void setPointer(Pointer p) {
        throw new UnsupportedOperationException("Immutable reference");
    }
};

public void listen() {
    try {


        HANDLE handle = null;
        do {
            handle = OpenEventW(2031619, false, new WString("event_name"));
            if(handle == null) {
                System.out.print("Handle is null\n");
            }
            Thread.sleep(500);
        } while (handle == null);

        while(true){
            // 50 second timeout
            int result = WaitForSingleObject(handle, 50000);
            if(result == 0){
                System.out.print("Handle signaled\n");
            }
            else if (result == 258){
                System.out.print("Timed out\n");
            }
            else{
                System.out.print("Handle not signaled\n");
                System.out.print(result);
            }
            System.out.print(result);
            //System.out.print(handle);
            Thread.sleep(100);
        }
    }
    catch (Exception exc)
    {
        System.out.print(exc);
        //Thread.sleep(10000);

        //writer.writeln(exc);
    }

}

public static void main(String[] args) {
    WinEventListener listener = new WinEventListener();
    listener.listen();
}

}

什么是不成功?代码在哪里失败?OpenEventW返回什么?如果任何API失败,它们是如何失败的?我看不到任何对GetLastError的调用。您好,很抱歉,我在很长一段时间后才写信。我修改了代码并添加了如下GetLastError:public static native int GetLastError;每次尝试获取handle后我都会调用它:handle=OpenEventW2,false,newwstringvlit_SERVER_数据;logger.debugAfter打开事件:+GetLastError;这个调用总是返回0,这样就不会出现我在文档中发现的故障。永不消失的hanle仍然为空。有没有可能操作系统中还没有这样的事件?C++应用程序的作者们说,如果文档告诉你,应该只调用GETLASTULL错误。通常,只有在函数调用失败的情况下才会这样做。例如,OpenEvent返回NULL表示失败。然后才调用GetLastError。但是您必须阅读每个API函数的文档,因为错误处理是不同的。GetLastError返回0。OpenEventW返回NULL。如果有任何错误,在GetLastError中调用OpenEventW后不应该有0值,对吗?请问OpenEventW和OpenEvent函数的区别是什么?我无法在文档中找到它。是否有可能我使用了错误的字符串值?是不是应该打电话?它应该显式编码为UNICODE吗?