Pregunta

Me gustaría llegar a consultar Windows Vista servicio de búsqueda directa (o indirectamente) de Java.

Yo sé que es posible realizar consultas mediante la búsqueda-EM: protocolo, pero me gustaría consumir el resultado dentro de la aplicación

.

He encontrado una buena información en el de Windows API de búsqueda, pero ninguno relacionado con Java.

Me marcar como aceptado la respuesta que proporciona información útil y definitiva sobre cómo lograr esto.

Gracias de antemano.

Editar

¿Alguien tiene una muestra JACOB, antes de que pueda marcar esto como aceptado? :)

¿Fue útil?

Solución

Es posible que desee ver en una de las tecnologías de integración de Java-COM. He trabajado personalmente con Jacob (Java Puente COM):

Lo que era bastante engorroso (piensa trabajar exclusivamente con la reflexión), pero consiguió el trabajo hecho por mí (la prueba rápida del concepto, el acceso a MapPoint desde dentro de Java).

El único otro tipo de tecnología yo sepa es Jawin, pero no tengo ninguna experiencia personal con:

Actualización 04/26/2009: Sólo por el gusto de hacerlo, lo hice más investigación en búsqueda de Microsoft Windows, y encontré una manera fácil de integrar con él utilizando OLE DB. Aquí hay algo de código que he escrito como una prueba de concepto:

public static void main(String[] args) {
    DispatchPtr connection = null;
    DispatchPtr results = null;
    try {
        Ole32.CoInitialize();
        connection = new DispatchPtr("ADODB.Connection");
        connection.invoke("Open",
            "Provider=Search.CollatorDSO;" +
            "Extended Properties='Application=Windows';");
        results = (DispatchPtr)connection.invoke("Execute",
            "select System.Title, System.Comment, System.ItemName, System.ItemUrl, System.FileExtension, System.ItemDate, System.MimeType " +
            "from SystemIndex " +
            "where contains('Foo')");
        int count = 0;
        while(!((Boolean)results.get("EOF")).booleanValue()) {
            ++ count;
            DispatchPtr fields = (DispatchPtr)results.get("Fields");
            int numFields = ((Integer)fields.get("Count")).intValue();

            for (int i = 0; i < numFields; ++ i) {
                DispatchPtr item =
                    (DispatchPtr)fields.get("Item", new Integer(i));
                System.out.println(
                    item.get("Name") + ": " + item.get("Value"));
            }
            System.out.println();
            results.invoke("MoveNext");
        }
        System.out.println("\nCount:" + count);
    } catch (COMException e) {
        e.printStackTrace();
    } finally {
        try {
            results.invoke("Close");
        } catch (COMException e) {
            e.printStackTrace();
        }
        try {
            connection.invoke("Close");
        } catch (COMException e) {
            e.printStackTrace();
        }
        try {
            Ole32.CoUninitialize();
        } catch (COMException e) {
            e.printStackTrace();
        }
    }
}

Para compilar este, que necesita para asegurarse de que el JAR Jawin está en la ruta de clases, y que jawin.dll está en su camino (o propiedad del sistema java.library.path). Este código simplemente abre una conexión ADO al índice de búsqueda de escritorio de Windows locales, las consultas de documentos con la palabra clave "Foo", e imprimir algunas propiedades clave de los documentos resultantes.

Déjame saber si usted tiene alguna pregunta, o yo necesito aclarar nada.

Actualización 04/27/2009: He intentado implementar lo mismo en Jacob así, y va a hacer algunos puntos de referencia para comparar las diferencias de rendimiento entre los dos. Puedo estar haciendo algo mal en Jacob, pero parece ser consistente utilizando 10 veces más memoria. Voy a estar trabajando en una aplicación JCOM y com4j así, si tengo algún tiempo, y tratar de averiguar algunas peculiaridades que creo que son debido a la falta de seguridad de los subprocesos en alguna parte. Incluso puede intentar una solución basada en JNI. Espero ser hecho con todo en 6-8 semanas.

Actualización 04/28/2009: Esto es sólo una actualización para aquellos que han estado siguiendo y curioso. Resulta que no hay problemas de threads, sólo tenía que cerrar explícitamente mis recursos de bases de datos, ya que las conexiones OLE DB se agruparon, presumiblemente, a nivel de sistema operativo (que probablemente debería haber cerrado las conexiones de todos modos ...). Creo que no voy a ser más actualizaciones a esto. Déjame saber si alguien se encuentra con algún problema con esto.

Actualización 05/01/2009: Añadido JACOB ejemplo según la petición del Oscar. Esto pasa por la misma secuencia exacta de las llamadas desde un punto de vista COM, simplemente usando JACOB. Si bien es cierto JACOB se ha trabajado mucho más activa en los últimos tiempos, también me doy cuenta de que es todo un cerdo de la memoria (10x utiliza más memoria que la versión Jawin)

public static void main(String[] args) {
    Dispatch connection = null;
    Dispatch results = null;

    try {
        connection = new Dispatch("ADODB.Connection");
        Dispatch.call(connection, "Open",
            "Provider=Search.CollatorDSO;Extended Properties='Application=Windows';");
        results = Dispatch.call(connection, "Execute",
            "select System.Title, System.Comment, System.ItemName, System.ItemUrl, System.FileExtension, System.ItemDate, System.MimeType " +
            "from SystemIndex " +
            "where contains('Foo')").toDispatch();
        int count = 0;
        while(!Dispatch.get(results, "EOF").getBoolean()) {
            ++ count;
            Dispatch fields = Dispatch.get(results, "Fields").toDispatch();
            int numFields = Dispatch.get(fields, "Count").getInt();

            for (int i = 0; i < numFields; ++ i) {
                Dispatch item =
                    Dispatch.call(fields, "Item", new Integer(i)).
                    toDispatch();
                System.out.println(
                    Dispatch.get(item, "Name") + ": " +
                    Dispatch.get(item, "Value"));
            }
            System.out.println();
            Dispatch.call(results, "MoveNext");
        }
    } finally {
        try {
            Dispatch.call(results, "Close");
        } catch (JacobException e) {
            e.printStackTrace();
        }
        try {
            Dispatch.call(connection, "Close");
        } catch (JacobException e) {
            e.printStackTrace();
        }
    }
}

Otros consejos

Como algunos puestos aquí sugieren que puede tender un puente entre Java y .NET o COM utilizando marcos comerciales o libres como JACOB, JNBridge, J-Integra etc .. En realidad, tuve una experiencia con uno de estos terceros (un caro uno :-)) y debo decir que haré todo lo posible para evitar la repetición de este error en el futuro. La razón es que implica muchas cosas "vudú" realmente no se puede depurar, es muy complicado de entender cuál es el problema cuando las cosas van mal.

La solución que sugeriría a implementar es la creación de una aplicación .NET simple que hace que las llamadas reales a la API de búsqueda de Windows. Después de hacerlo, es necesario establecer un canal de comunicación entre este componente y el código Java. Esto se puede hacer de varias maneras, por ejemplo mediante mensajería a una pequeña base de datos que la aplicación va a tirar de forma periódica. O registro de este componente en la máquina de IIS (si existe) y exponer sencilla API WS para comunicarse con él.

Sé que puede sonar complicado, pero las claras ventajas son: a) que se comunica con la búsqueda de Windows API utilizando el lenguaje que entiende (.NET o COM), b) controlar todas las rutas de aplicaciones

.

Cualquier razón por la cual no se podía utilizar sólo Runtime.exec() para consultar a través de search-ms y leer el BufferedReader con el resultado del comando? Por ejemplo:

public class ExecTest {
    public static void main(String[] args) throws IOException {
        Process result = Runtime.getRuntime().exec("search-ms:query=microsoft&");

        BufferedReader output = new BufferedReader(new InputStreamReader(result.getInputStream()));
        StringBuffer outputSB = new StringBuffer(40000);
        String s = null;

        while ((s = output.readLine()) != null) {
            outputSB.append(s + "\n");
            System.out.println(s);
        }

        String result = output.toString();
    }
}

Hay varias bibliotecas que hay para llamar a objetos COM desde Java, algunos son de código abierto (pero su curva de aprendizaje es mayor) algunos son de código cerrado y tiene una curva de aprendizaje más rápido. Un ejemplo de código cerrado es EZCom . Los comerciales tienden a centrarse en llamar a Java desde las ventanas, así, algo que nunca he visto en código abierto.

En su caso, lo que sugeriría que hacer es frente a la llamada en su propia clase .NET (supongo que el uso de C #, ya que es más cercano a Java sin entrar en el J controvertido #), y se centran en hacer que la interoperabilidad con el DLL .NET. De esa manera la programación de las ventanas se hace más fácil, y la interfaz entre Windows y Java es más simple.

Si usted está buscando la manera de utilizar una biblioteca java com, el MSDN es el lugar equivocado. Pero el MSDN le ayudará a escribir lo que necesita desde dentro de .NET, y luego buscar en la biblioteca com tutoriales sobre la invocación de los uno o dos métodos que necesita de sus objetos .NET.

EDIT:

Teniendo en cuenta lo expuesto en las respuestas sobre el uso de un servicio Web, usted podría (y probablemente tendrá mejor suerte) construir una pequeña aplicación .NET que llama a un servidor web Java embebido en lugar de tratar de hacer .NET tienen el servicio web integrado y tiene java sea el consumidor de la llamada. Para un servidor web incorporado, mi investigación mostró Winstone para ser bueno. No es la más pequeña, pero es mucho más flexible.

La manera de conseguir que el trabajo es poner en marcha la aplicación .NET desde Java, y tener la aplicación .NET llamar al servicio web en un temporizador o un bucle para ver si hay una solicitud, y si no, el proceso de y enviar la respuesta.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top