2009-04-23 4 views
6

Java에서 직접 (또는 간접적으로) Windows Vista 검색 서비스를 쿼리하고 싶습니다.Java에서 쿼리 Windows 검색

search-ms : 프로토콜을 사용하여 쿼리하는 것이 가능하다는 것을 알고 있지만 앱 내에서 결과를 사용하고 싶습니다.

Windows Search API에 좋은 정보가 있지만 자바와 관련이 없습니다.

나는 이것을 달성하는 방법에 대한 유용하고 명확한 정보를 제공하는 대답을 받아 들였습니다.

미리 감사드립니다.

편집

I 허용으로이를 표시 할 수 있습니다 전에 누군가가, 야곱의 샘플이 있습니까? :

답변

19

Java-COM 통합 기술 중 하나를 살펴볼 수 있습니다. (반사와 독점적으로 일하고 생각)

다소 복잡했지만, 나를 위해 수행 할 작업 (개념의 빠른 증거를 가지고 : 나는 개인적으로 JACOB (자바 COM 다리)와 함께 일했다 Java 내에서 MapPoint에 액세스).

내가 Jawin입니다 알고 있어요,하지만 난 그것으로 어떤 개인적인 경험이없는 유일한 등의 기술 :

업데이트 2009년 4월 26일를 : Microsoft Windows Search에 대한 더 많은 연구를 수행했으며 OLE DB를 사용하여 쉽게 통합 할 수있는 방법을 발견했습니다. 여기 개념의 증거로 쓴 일부 코드입니다 :

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(); 
     } 
    } 
} 

이를 컴파일하려면, 당신은 JAWIN의 JAR이 클래스 경로에 있는지 확인해야합니다, 그리고 그 jawin.dll는 경로에 (또는 자바 .library.path 시스템 특성). 이 코드는 로컬 Windows 데스크톱 검색 인덱스에 대한 ADO 연결을 열고 키워드 "Foo"가있는 문서를 쿼리하고 결과 문서에 몇 가지 주요 속성을 인쇄합니다.

질문이 있거나 알려주는 것이 필요하면 알려주세요.

업데이트 04/27/2009 : 나뿐만 아니라 야곱에서 같은 일을 구현했는데, 둘 사이의 성능 차이를 비교하기 위해 몇 가지 벤치 마크를하고있을 것입니다. 나는 JACOB에서 뭔가 잘못하고있을 수도 있지만 일관되게 10 배 더 많은 메모리를 사용하고있는 것 같습니다. jcom과 com4j 구현에 대해서도 일할 것입니다. 시간이 있다면, 어딘가에 스레드 안전성이 부족하기 때문에 믿을만한 몇 가지 단점을 파악하려고 시도해보십시오. 심지어 JNI 기반 솔루션을 사용해 볼 수도 있습니다.나는 6-8 주 안에 모든 일이 끝나기를 기대합니다.

업데이트 04/28/2009 : 이것은 다음 호기심 많은 사람들을위한 업데이트입니다. OLE DB 연결은 아마도 OS 레벨에서 풀링되었으므로 (아마도 어쨌든 연결을 닫아야 했음), 스레딩 문제가 없다는 것을 알았습니다. 데이터베이스 리소스를 명시 적으로 닫아야했습니다. 나는 이것에 대한 더 이상의 업데이트가 없을 것이라고 생각한다. 누군가가이 문제에 부딪치게되면 알려주십시오.

업데이트 05/01/2009 : Oscar의 요청에 따라 JACOB 예제가 추가되었습니다. 이것은 JACOB을 사용하는 것과 똑같은 COM 관점에서의 동일한 호출 순서를 거친다. 사실 야곱은 훨씬 더 적극적으로 최근에 작업 한되었습니다이지만, 나 또한

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(); 
     } 
    } 
} 
+0

윈도우 프로그래밍에 대해 잘 모릅니다. -S 이전에이 라이브러리를 본 적이 있지만 많이 얻지는 못했습니다. 더 이상 나는 다음에 무엇을해야할지 모르겠다. jacob에서 작동하도록 MSDN 설명서에서 샘플 검색을 수행 할 수 있습니까? – OscarRyz

+0

이것은 매우 흥미 롭습니다! 저는 컴퓨터 과학을 공부하는 초보자이고, "창문에 들어가는"것에 대해 더 많이 배울 수 있고, 자바 나 다른 언어에서 그런 것들을 할 수있는 곳이 궁금합니다. 도서 또는 웹 페이지의 제목은 무엇입니까? 나는 msdn을 읽는 데 일을 사용했지만 초보자는 아닙니다. :) – Johannes

+0

저는 Jawin 설명서를 간략하게 살펴본 후 Microsoft에서 제공하는 COM 구성 요소 API 참조를 보았습니다. . 그것은 시작이지만, 더 복잡한 것을 시도한다면 더 많은 문제를 겪게 될 것이라고 생각합니다. –

1

search-ms을 통해 쿼리하고 BufferedReader을 통해 쿼리 할 수없는 이유는 무엇입니까? 예 :

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(); 
    } 
} 
+0

두 번째 행을 읽습니다. 내가 할 수 있었던 일은 Windows 탐색기를 호출하여 결과를 표시하는 것입니다. 정확하게 필요한 것은 아닙니다 (2 번 줄에서 읽음). 또는, 나는 무엇인가 여기에서 놓치고 있냐? – OscarRyz

+0

아, 네 말이 맞아. Windows 검색에 익숙하지 않고 Mac에서 실행 중이므로 탐색기를 호출한다는 사실을 알지 못했습니다. 미안합니다! –

+0

문제 없습니다. 어쨌든 도움을 주셔서 감사합니다. BTW, 귀하의 게시물을 다음과 같이 보여야합니다 : http://pastebin.com/fa34637e – OscarRyz

0

호출하기위한 거기에 몇 가지 라이브러리가 있습니다 (10 배 많은 메모리가 Jawin 버전으로 사용) 꽤 메모리 돼지가의 통지 자바에서 COM 개체, 일부 opensource (하지만 그들의 학습 곡선이 높다) 일부는 폐쇄 소스이며 빠른 학습 곡선이 있습니다. 닫힌 소스 예제는 EZCom입니다. 상업적인 것들은 윈도우즈에서 자바를 호출하는데 초점을 맞추는 경향이 있는데, 나는 오픈 소스에서 본 적이 없다.

귀하의 경우, 내가하는 것이 좋습니다 제안은 귀하의 자신의. NET에서 클래스 (나는 C#을 논쟁의 여지가 J #에 들어 가지 않고 Java에 가장 가까운 것 같아요), 그리고 상호 운용성을 만들기에 집중 .NET dll. 그렇게하면 Windows 프로그래밍이 쉬워지고 Windows와 Java 간의 인터페이스가 더 간단 해집니다.

java com 라이브러리를 사용하는 방법을 찾고있는 경우 MSDN이 잘못되었습니다. 그러나 MSDN은 .NET에서 필요한 것을 작성하는 데 도움이되며 .NET 객체에서 필요로하는 하나 또는 두 가지 방법을 호출하는 방법에 대한 com 라이브러리 자습서를 살펴보십시오.

편집 :

, 당신은 (그리고 아마도 더 좋은 행운이있을 것이다) 만들려고하기보다는 임베디드 자바 웹 서버를 호출하는 작은 .NET 응용 프로그램을 구축 할 수있는 웹 서비스를 사용하는 방법에 대한 답변에서 토론을 감안할 때 .NET에는 내장 된 웹 서비스가 있으며 Java를 호출 소비자로 삼아야합니다. 임베디드 웹 서버의 경우 내 연구 결과 Winstone이 좋음을 나타냅니다. 가장 작은 것은 아니지만 훨씬 더 유연합니다.

작동을 얻는 방법은 자바에서 .NET 응용 프로그램을 시작하고. NET 응용 프로그램에서 타이머 또는 루프의 웹 서비스를 호출하여 요청이 있는지 확인하고, 그것을 처리하고 응답을 보내십시오.

+0

정확히 java/com 라이브러리를 찾지는 않습니다 (적어도 그 질문의 근거는 아닙니다). Java에서 Windows 검색을 사용하십시오. (비록 내가 가지고있어 몇 가지 대답은 자바/컴 lib 디렉토리에 가서) – OscarRyz

+0

그 같은 Windows 검색을 소비하는 유일한 방법은 Windows API와 함께, 그래서 그 Windows API와 상호 작용하는 유일한 방법은 COM과 같은 것입니다 , DCOM 또는 CORBA 또는 일부 종류의 소켓 레이어 (웹 서비스와 같은). 그래서 우리 모두는 당신을 java/com 브리지로 안내합니다. – Yishai

3

JACOB, JNBridge, J-Integra 등과 같은 상용 또는 무료 프레임 워크를 사용하여 Java와 .NET 또는 COM 사이에서 다리를 놓을 수있는 게시물은 거의 없습니다. 실제로 이러한 타사 중 하나 비싼 하나 :-)) 나는이 실수를 앞으로 반복하지 않도록 최선을 다할 것입니다. 그 이유는 실제로 디버깅 할 수없는 많은 "부두교 (voodoo)"물건을 포함하고 있기 때문에 상황이 잘못 될 때 문제가 무엇인지 이해하는 것은 매우 복잡합니다.

구현하기를 제안하는 해결책은 Windows 검색 API를 실제로 호출하는 간단한 .NET 응용 프로그램을 만드는 것입니다. 그런 다음이 구성 요소와 Java 코드 사이에 통신 채널을 설정해야합니다. 이 작업은 다양한 방법으로 수행 할 수 있습니다. 예를 들어 응용 프로그램에서 주기적으로 가져올 작은 DB에 메시징을 수행 할 수 있습니다. 또는 시스템 IIS (존재하는 경우)에이 구성 요소를 등록하고 간단한 WS API를 노출하여 통신 할 수 있습니다.

귀찮은 것처럼 들리 겠지만 확실한 장점은 다음과 같습니다. a) 이해하는 언어 (.NET 또는 COM)를 사용하여 Windows 검색 API와 통신하고, b) 모든 응용 프로그램 경로를 제어합니다.

+0

저는 실제로 ws를 사용하여 두 번째 옵션을 생각했습니다. 나는 가벼운 무게의 자바 프레임 워크/웹 서버를 사용할 수 있다는 것을 안다. 같은 목적을 위해 IIS가 아닌 다른 것이 있는지는 모르겠다. IIS는 완전한 미래의 웹 서버이지만 모든 것은 기본적인 http 통신이 필요합니다. – OscarRyz

+0

가벼운 Java 서버가 많이 있지만 문제를 이해할 수 있으면 Java 서버가 필요합니다.웹 서버에서 실행되는 NET 코드 (Java가 아님)를 사용하면 IIS가 가장 간단하고 간단한 선택이 될 것입니다. – LiorH

+0

Hey Lior, 이것이 더 복잡한 경우 동의하는 경향이 있지만, 그냥 OLE DB 호출), 나는 Java/COM 호출이 문제가되어서는 안된다고 생각합니다. 필자는이 문제에 대해 읽고 있었으며 Java COM 통합이 악몽처럼 느껴질 수 있습니다. 특히 스레드가 작동하는 경우 (예 : COM 객체를 공유하는 여러 Java 스레드). –