错误 com4j.ComException: 80004005 .\invoke.cpp:51 打开 windows 和选定的项目

Error com4j.ComException: 80004005 .\invoke.cpp:51 while getting open windows and selected items

我需要在 Windows 资源管理器中获取所有选定的文件和文件夹。我正在使用 com4j 访问 win Shell32 API (感谢 Tom91136,如果您需要了解如何安装和初始化 com4j,请参考 this

此代码 class 在 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() 方法。它工作正常,但如果我关闭 Window.

,我会收到以下错误
    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" 方法有问题。

我猜你的问题是关于计时器的。如果有一个计时器并且 list() 方法每秒 运行 那么当你关闭一个 window 时,getIShellFolderViewDual3() 方法也会同时尝试访问一个关闭的 window .

使用前检查 "browser" 对象是否可见且不为空。

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";
                            }
                        }
                    }
                }
            }
        }