Ошибка com4j.ComException: 80004005 .\invoke.cpp:51 при получении открытых окон и выбранных элементов

Мне нужно получить все выбранные файлы и папки в проводнике Windows. Я использую com4j для доступа к win Shell32 API (спасибо Tom91136, см. это, если вам нужно научиться устанавливать и инициализировать com4j).

Этот класс кода получает выбранные файлы или папки в проводнике 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;
        }
    }
}

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

    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)

Я начал использовать try-catch и получил следующее:

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

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


person amone    schedule 24.04.2015    source источник
comment
Какую версию com4j вы используете? Вы компилировали com4j из исходников или использовали бинарный дистрибутив?   -  person tom91136    schedule 24.04.2015
comment
Я скачал последнюю версию и добавил файлы jar в свой проект.   -  person amone    schedule 24.04.2015
comment
еще раз спасибо за вашу помощь @tom91136   -  person amone    schedule 24.04.2015


Ответы (1)


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

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

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";
                            }
                        }
                    }
                }
            }
        }
person onivi    schedule 24.04.2015