无法使用 jinterop 打开 dcom 会话

Posted

技术标签:

【中文标题】无法使用 jinterop 打开 dcom 会话【英文标题】:Can't open a dcom session with jinterop 【发布时间】:2013-04-10 17:17:52 【问题描述】:

我正在尝试使用 jinterop 在远程 PC 上运行 wmi 查询,但我什至无法启动 dcom 会话。我知道 wmi 正在工作,因为我可以使用 powershell\wmic\vbscript 毫无问题地访问它。此外,我们的 Windows 客户端已禁用文件共享。

这是我正在尝试的:

import static org.jinterop.dcom.impls.JIObjectFactory.narrowObject;
import static org.jinterop.dcom.impls.automation.IJIDispatch.IID;

import java.net.UnknownHostException;

import org.jinterop.dcom.common.JIException;
import org.jinterop.dcom.core.JIComServer;
import org.jinterop.dcom.core.JISession;
import org.jinterop.dcom.impls.automation.IJIDispatch;
import static org.jinterop.dcom.core.JIProgId.valueOf;
import org.jinterop.dcom.core.JIVariant;
import org.jinterop.dcom.core.JIString;

public class SimpleServiceManager 

    public static void main(String[] args) 
        String domain = "mydom";
        String hostname = "remotepc";
        String username = "myusername";
        String password = "mypass";

        JISession dcomSession = JISession.createSession(domain, username, password);
        JIComServer comServer;
        try 
            comServer = new JIComServer(valueOf("WbemScripting.SWbemLocator"), hostname, dcomSession);

            IJIDispatch wbemLocator = (IJIDispatch) narrowObject(comServer.createInstance().queryInterface(IID));

            Object[] params = new Object[] 
                    new JIString(hostname),
                    new JIString("ROOT\\CIMV2"),
                    JIVariant.OPTIONAL_PARAM(),
                    JIVariant.OPTIONAL_PARAM(),
                    JIVariant.OPTIONAL_PARAM(),
                    JIVariant.OPTIONAL_PARAM(),
                    new Integer(0),
                    JIVariant.OPTIONAL_PARAM()
            ;
            JIVariant results[] = wbemLocator.callMethodA("ConnectServer", params);
            IJIDispatch wbemServices = (IJIDispatch) narrowObject(results[0].getObjectAsComObject());  
         catch (UnknownHostException e) 
            // TODO Auto-generated catch block
            e.printStackTrace();
         catch (JIException e) 
            // TODO Auto-generated catch block
            e.printStackTrace();
        
    
 

给我这个:

Apr 10, 2013 1:14:38 PM org.jinterop.dcom.common.JISystem logSystemPropertiesAndVersion
INFO: j-Interop Version = j-Interop 2.08

Apr 10, 2013 1:14:38 PM org.jinterop.dcom.common.JISystem logSystemPropertiesAndVersion
INFO: java.runtime.name = Java(TM) SE Runtime Environment
sun.boot.library.path = C:\Program Files\Java\jre7\bin
java.vm.version = 23.7-b01
java.vm.vendor = Oracle Corporation
java.vendor.url = http://java.oracle.com/
path.separator = ;
java.vm.name = Java HotSpot(TM) Client VM
file.encoding.pkg = sun.io
user.country = US
user.script = 
sun.java.launcher = SUN_STANDARD
sun.os.patch.level = Service Pack 1
java.vm.specification.name = Java Virtual Machine Specification
user.dir = C:\Users\myusername\Google Drive\code\Workspaces\Eclipse IDE for Java Developers 422\Jinterop
java.runtime.version = 1.7.0_17-b02
java.awt.graphicsenv = sun.awt.Win32GraphicsEnvironment
java.endorsed.dirs = C:\Program Files\Java\jre7\lib\endorsed
os.arch = x86
java.io.tmpdir = C:\Users\myusername\AppData\Local\Temp\
line.separator = 

java.vm.specification.vendor = Oracle Corporation
user.variant = 
os.name = Windows 7
sun.jnu.encoding = Cp1252
java.library.path = C:\Program Files\Java\jre7\bin;C:\Windows\Sun\Java\bin;...
java.specification.name = Java Platform API Specification
java.class.version = 51.0
sun.management.compiler = HotSpot Client Compiler
os.version = 6.1
user.home = C:\Users\myusername
user.timezone = America/New_York
java.awt.printerjob = sun.awt.windows.WPrinterJob
file.encoding = Cp1252
java.specification.version = 1.7
java.class.path = C:\Users\myusername\Google Drive\code\Workspaces\Eclipse IDE for Java Developers 422\Jinterop\bin;C:\Users\myusername\Google Drive\code\Workspaces\Eclipse IDE for Java Developers 422\Jinterop\libs\j-interop.jar;C:\Users\myusername\Google Drive\code\Workspaces\Eclipse IDE for Java Developers 422\Jinterop\libs\j-interopdeps.jar;C:\Users\myusername\Google Drive\code\Workspaces\Eclipse IDE for Java Developers 422\Jinterop\libs\jcifs-1.2.19.jar
user.name = myusername
java.vm.specification.version = 1.7
sun.java.command = SimpleServiceManager
java.home = C:\Program Files\Java\jre7
sun.arch.data.model = 32
user.language = en
java.specification.vendor = Oracle Corporation
awt.toolkit = sun.awt.windows.WToolkit
java.vm.info = mixed mode, sharing
java.version = 1.7.0_17
java.ext.dirs = C:\Program Files\Java\jre7\lib\ext;C:\Windows\Sun\Java\lib\ext
sun.boot.class.path = C:\Program Files\Java\jre7\lib\resources.jar;C:\Program Files\Java\jre7\lib\rt.jar;C:\Program Files\Java\jre7\lib\sunrsasign.jar;C:\Program Files\Java\jre7\lib\jsse.jar;C:\Program Files\Java\jre7\lib\jce.jar;C:\Program Files\Java\jre7\lib\charsets.jar;C:\Program Files\Java\jre7\lib\jfr.jar;C:\Program Files\Java\jre7\classes
java.vendor = Oracle Corporation
file.separator = \
java.vendor.url.bug = http://bugreport.sun.com/bugreport/
sun.io.unicode.encoding = UnicodeLittle
sun.cpu.endian = little
sun.desktop = windows
sun.cpu.isalist = pentium_pro+mmx pentium_pro pentium+mmx pentium i486 i386 i86

Apr 10, 2013 1:14:38 PM org.jinterop.dcom.core.JIComOxidRuntime$ClientPingTimerTask run
INFO: Running ClientPingTimerTask !
Apr 10, 2013 1:14:38 PM org.jinterop.dcom.core.JISession createSession
INFO: Created Session: -1745354837
Apr 10, 2013 1:14:38 PM org.jinterop.dcom.core.JIComOxidRuntime$ServerPingTimerTask run
INFO: Running ServerPingTimerTask !
Apr 10, 2013 1:14:38 PM org.jinterop.dcom.core.JISession$Release_References_TimerTask run
INFO: Release_References_TimerTask:[RUN] Session:  -1745354837 , listOfDeferencedIpids.size(): 0
Apr 10, 2013 1:14:38 PM org.jinterop.dcom.common.JISystem saveDBPathAndLoadFile
INFO: progIdVsClsidDB: 
org.jinterop.dcom.common.JIException: Message not found for errorCode: 0xC0000034
    at org.jinterop.winreg.smb.JIWinRegStub.winreg_OpenHKLM(JIWinRegStub.java:115)
    at org.jinterop.dcom.core.JIProgId.getIdFromWinReg(JIProgId.java:130)
    at org.jinterop.dcom.core.JIProgId.getCorrespondingCLSID(JIProgId.java:162)
    at org.jinterop.dcom.core.JIComServer.<init>(JIComServer.java:413)
    at SimpleServiceManager.main(SimpleServiceManager.java:25)
Caused by: jcifs.smb.SmbException: The system cannot find the file specified.
    at jcifs.smb.SmbTransport.checkStatus(SmbTransport.java:522)
    at jcifs.smb.SmbTransport.send(SmbTransport.java:622)
    at jcifs.smb.SmbSession.send(SmbSession.java:239)
    at jcifs.smb.SmbTree.send(SmbTree.java:109)
    at jcifs.smb.SmbFile.send(SmbFile.java:718)
    at jcifs.smb.SmbFile.open0(SmbFile.java:923)
    at jcifs.smb.SmbFile.open(SmbFile.java:940)
    at jcifs.smb.SmbFileOutputStream.<init>(SmbFileOutputStream.java:142)
    at jcifs.smb.TransactNamedPipeOutputStream.<init>(TransactNamedPipeOutputStream.java:32)
    at jcifs.smb.SmbNamedPipe.getNamedPipeOutputStream(SmbNamedPipe.java:187)
    at rpc.ncacn_np.RpcTransport.attach(RpcTransport.java:92)
    at rpc.Stub.attach(Stub.java:106)
    at rpc.Stub.call(Stub.java:110)
    at org.jinterop.winreg.smb.JIWinRegStub.winreg_OpenHKLM(JIWinRegStub.java:113)
    ... 4 more

为什么会抛出 jcifs.smb.SmbException? WMI 不使用 smb 那么为什么我会看到这个错误? jinterop 是否要求客户端启用 windows 文件共享?

【问题讨论】:

好吧,我应该对此进行更多研究,但似乎 jinterop 需要在远程 PC 上启动远程注册表,这意味着我无法使用它。但我仍然很好奇文件共享是否是一项要求。 我的经验。当您要使用服务器回调时,必须在客户端启用 jcifs samba 我在使用 prodId 而不是 clsid 时收到此错误。查看 dcom 配置以找到映射。 【参考方案1】:

在这个thread中有一个关于这个问题的讨论。

快速总结:

首先,确保已启用远程注册表服务。

其次,确保 j-interop 没有使用自动注册(否则会遇到拒绝访问错误):

JISystem.setAutoRegisteration(false);

第三,确保防火墙没有干扰。

【讨论】:

【参考方案2】:

我正在回复您的声明“我什至无法启动 dcom 会话”。这是使用 j-interop 获取会话的代码。

try 
        args[0] = "x.y.z.w";
        String domain       = "";//i am using it as blank
        String username     = "username";//user who logs in to the system as admin
        String password     = "password";// used by admin to login to windows pc

        JISystem.getLogger().setLevel(Level.FINEST);
        JISystem.setInBuiltLogHandler(false);
        JISystem.setAutoRegisteration(true);
        JISession session3 = JISession.createSession(domain,username,password);
        session3.useSessionSecurity(true);
        System.out.println(" session3 "+session3);
    catch(Exception e)
        e.printStackTrace();
    

你会看到输出 session3 org.jinterop.dcom.core.JISession@a46bc929

【讨论】:

以上是关于无法使用 jinterop 打开 dcom 会话的主要内容,如果未能解决你的问题,请参考以下文章

Microsoft Office 2007 的 DCOM 配置 - 无法打开文档模板 (.dotm)

WindowsServers2008R2 DCOM 无法使用任何配置的协议与计算机通讯

使用 DCOM 处理线程

使用 J-Interop 库访问 SWbemObject 对象属性

无法写入内容:无法延迟初始化角色集合,无法初始化代理 - 无会话

会话跟踪