2015-04-24 10 views
1

Мне нужно получить все выбранные файлы и папки в Проводнике Windows. Я использую com4j для доступа к win Shell32 API (спасибо Tom91136, см. this, если вам нужно узнать, как вы можете установить и инициализировать com4j).Ошибка com4j.ComException: 80004005. Invoke.cpp: 51 при получении открытых окон и выбранных элементов

Этот класс кода получает выбранные файлы или папки в проводнике Windows и печатает.

import java.io.File; 
import com4j.*; 
import test.wsh.*; 
import java.util.*; 
import java.util.Timer; 
import javax.swing.*; 


public class DetectSelection { 

    public static void main(String[] argv) 
    { 
      list(); //there is a timer actually, calls every second 
    } 

    public static void list(){ 
     System.out.println("SELECTION DETECT:"); 

     String newResults=""; 

     try 
     { 
      List<IWebBrowser2> browsers = getIWebBrowser2(); 
      for(IWebBrowser2 browser : browsers){ 
       IShellFolderViewDual3 view = getIShellFolderViewDual3(browser); 
       if (view != null && browser.visible()) { 

        FolderItems items = view.selectedItems(); 

        for (Com4jObject object : items) { 
         FolderItem item = object.queryInterface(FolderItem.class); 
         if (item != null) { 
          newResults+=item.path()+" - "+item.type()+"\n\n"; 
         } 
        } 
       } 
      } 
     } 
     catch(Exception error) 
     { 
      System.out.println("Error in list: "+error.toString()); 
     } 

     System.out.println(newResults); 
    } 

    public static List<IWebBrowser2> getIWebBrowser2() { 
     // TODO this can be potentially optimized 
     try 
     { 
      List<IWebBrowser2> rWindows=new ArrayList<IWebBrowser2>(); 

      IShellWindows windows = ClassFactory.createShellWindows() 
        .queryInterface(IShellWindows.class); 
      for (Com4jObject window : windows) { 

       IWebBrowser2 browser = window.queryInterface(IWebBrowser2.class); 
        rWindows.add(browser); 
      } 
      return rWindows; 
     } 
     catch(Exception error) 
     { 
      System.out.println("Error in getIWebBrowser2: "+error.toString()); 
      return null; 
     } 
    } 

    public static IShellFolderViewDual3 getIShellFolderViewDual3(IWebBrowser2 browser) { 
     if (browser == null) 
      return null; 

     try 
     { 
      return browser.document().queryInterface(IShellFolderViewDual3.class); 
     } 
     catch(Exception error) 
     { 
      System.out.println("Error in getIShellFolderViewDual3: "+error.toString()); 
      return null; 
     } 
    } 
} 

Я разместил только важные детали. Я использую таймер, чтобы периодически проверять открытые файлы. Каждый раз вызывает список(). Он работает нормально, но я получаю ошибку ниже, если я закрываю окно.

com4j.ComException: 80004005 
.\invoke.cpp:517 
     at com4j.Wrapper.invoke(Wrapper.java:166) 
     at com.sun.proxy.$Proxy10.document(Unknown Source) 
     at DetectSelection.getIShellFolderViewDual3(DetectSelection.java:79) 
     at DetectSelection.list(DetectSelection.java:32) 
    Caused by: com4j.ComException: 80004005 Belirtilmemiş hata : Belirtilmemiş hata : .\invoke.cpp:517 
     at com4j.Native.invoke(Native Method) 
     at com4j.StandardComMethod.invoke(StandardComMethod.java:35) 
     at com4j.Wrapper$InvocationThunk.call(Wrapper.java:340) 
     at com4j.Task.invoke(Task.java:51) 
     at com4j.ComThread.run0(ComThread.java:153) 
     at com4j.ComThread.run(ComThread.java:134) 

Я начал использовать примерочный улов, и я получил это:

Error in getIShellFolderViewDual3: com4j.ComException: 80004005 .\invoke.cpp:517 

Что-то не так с методом "IShellFolderViewDual3".

+0

Какая версия com4j вы используете? Вы компилировали com4j из источника или использовали бинарный дистрибутив? – tom91136

+0

Я загрузил последнюю версию и добавил файлы jar в свой проект. – amone

+0

еще раз спасибо за помощь @ tom91136 – amone

ответ

1

Я думаю, ваша проблема касается таймера. Если есть таймер, и метод list() запускается каждую секунду, то при закрытии окна метод getIShellFolderViewDual3() также пытается получить доступ к закрывающему окну в одно и то же время.

Проверьте, является ли объект «браузер» видимым и не имеет значения null перед его использованием.

try 
     { 
      List<IWebBrowser2> browsers = getIWebBrowser2(); 
      for(IWebBrowser2 browser : browsers){ 
       if(browser.visible()) 
       { 

        IShellFolderViewDual3 view = getIShellFolderViewDual3(browser); 
        if (view != null && browser.visible()) { 

         FolderItems items = view.selectedItems(); 

         for (Com4jObject object : items) { 
          FolderItem item = object.queryInterface(FolderItem.class); 
          if (item != null) { 
           newResults+=item.path()+" - "+item.type()+"\n\n"; 
          } 
         } 
        } 
       } 
      } 
     } 
+0

выглядит как его работа, спасибо вам большое ... – amone