文档章节

100%纯java调用windows的wmi获取监控数据

NoahX
 NoahX
发布于 2012/08/16 18:17
字数 1414
阅读 9519
收藏 29

【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>>

纯java主要体现在可以跨平台调用com。所用的是j-Interop,它是100%纯java实现的com的调用

1、环境准备

a、windows要开启Remote Registry与Windows Management Instrumentation服务

b、修改安全策略

我系统是英文的,如果是中文系统,翻译为中文,相对应的查找并修改。

Administrative Tools>Local Security Policy>Local Policy>Security Policy>Network access: Sharing and security model for local accounts

修改为Classic(经典)

c、禁用放火墙

d、window2008系统注册表越狱(高版本的win)

需要修改regedit中HKEY_CLASSES_ROOT\CLSID\{76A64158-CB41-11D1-8B02-00600806D9B6}的权限,windows2008不再给Administrators完全控制权。

下载SetACL.exe,下载地址:http://files.helgeklein.com/downloads/SetACL/current/SetACL%20(executable%20version).zip

set_wmi_reg_acl.cmd

SetACL.exe -on "HKEY_CLASSES_ROOT\CLSID\{76A64158-CB41-11D1-8B02-00600806D9B6}" -ot reg -actn setowner -ownr "n:Administrators"
SetACL.exe -on "HKEY_CLASSES_ROOT\CLSID\{76A64158-CB41-11D1-8B02-00600806D9B6}" -ot reg -actn ace -ace "n:Administrators;p:full"

以超级管理员身份执行这个cms,就会把owner与完全控制权限授予Administrators组


2、程序代码

java类
package org.noah.wmitest;

import org.jinterop.dcom.common.JIException;
import org.jinterop.dcom.common.JISystem;
import org.jinterop.dcom.core.*;
import org.jinterop.dcom.impls.JIObjectFactory;
import org.jinterop.dcom.impls.automation.IJIDispatch;
import org.jinterop.dcom.impls.automation.IJIEnumVariant;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.net.UnknownHostException;
import java.util.logging.Level;

/**
 * Created with IntelliJ IDEA.
 * User: noah
 * Date: 8/16/12
 * Time: 8:00 AM
 * To change this template use File | Settings | File Templates.
 */
public class WmiService {

    private JIComServer m_ComStub = null;
    private IJIComObject m_ComObject = null;
    private IJIDispatch m_Dispatch = null;
    private String m_Address = null;
    private JISession m_Session = null;
    private IJIDispatch m_WbemServices = null;

    private static final String WMI_CLSID = "76A6415B-CB41-11d1-8B02-00600806D9B6";
    private static final String WMI_PROGID = "WbemScripting.SWbemLocator";

    private Logger logger = LoggerFactory.getLogger(this.getClass());


    public WmiService(String address) {
        JISystem.setAutoRegisteration(true);
        JISystem.getLogger().setLevel(Level.WARNING);
        m_Address = address;
    }

    public void query(String strQuery) {

        System.out.println("query:" + strQuery);

        JIVariant results[] = new JIVariant[0];
        try {
            results = m_WbemServices.callMethodA("ExecQuery", new Object[]{new JIString(strQuery), JIVariant.OPTIONAL_PARAM(), JIVariant.OPTIONAL_PARAM(), JIVariant.OPTIONAL_PARAM()});
            IJIDispatch wOSd = (IJIDispatch) JIObjectFactory.narrowObject((results[0]).getObjectAsComObject());

            int count = wOSd.get("Count").getObjectAsInt();

            IJIComObject enumComObject = wOSd.get("_NewEnum").getObjectAsComObject();
            IJIEnumVariant enumVariant = (IJIEnumVariant) JIObjectFactory.narrowObject(enumComObject.queryInterface(IJIEnumVariant.IID));

            IJIDispatch wbemObject_dispatch = null;

            for (int c = 0; c < count; c++) {

                Object[] values = enumVariant.next(1);
                JIArray array = (JIArray) values[0];
                Object[] arrayObj = (Object[]) array.getArrayInstance();
                for (int j = 0; j < arrayObj.length; j++) {
                    wbemObject_dispatch = (IJIDispatch) JIObjectFactory.narrowObject(((JIVariant) arrayObj[j]).getObjectAsComObject());
                }

                String str = (wbemObject_dispatch.callMethodA("GetObjectText_", new Object[]{1}))[0].getObjectAsString2();
                System.out.println("(" + c + "):");
                System.out.println(str);
                System.out.println();
            }


        } catch (JIException e) {
            e.printStackTrace();
        }
    }

    public void connect(final String domain, final String username, final String password) {
        try {

            m_Session = JISession.createSession(domain, username, password);
            m_Session.useSessionSecurity(true);
            m_Session.setGlobalSocketTimeout(5000);

            m_ComStub = new JIComServer(JIProgId.valueOf(WMI_PROGID), m_Address, m_Session);

            IJIComObject unknown = m_ComStub.createInstance();
            m_ComObject = unknown.queryInterface(WMI_CLSID);

            m_Dispatch = (IJIDispatch) JIObjectFactory.narrowObject(m_ComObject.queryInterface(IJIDispatch.IID));
            JIVariant results[] = m_Dispatch.callMethodA(
                    "ConnectServer",
                    new Object[]{
                            new JIString(m_Address),
                            JIVariant.OPTIONAL_PARAM(),
                            JIVariant.OPTIONAL_PARAM(),
                            JIVariant.OPTIONAL_PARAM(),
                            JIVariant.OPTIONAL_PARAM(),
                            JIVariant.OPTIONAL_PARAM(),
                            0,
                            JIVariant.OPTIONAL_PARAM()
                    }
            );

            m_WbemServices = (IJIDispatch) JIObjectFactory.narrowObject((results[0]).getObjectAsComObject());

        } catch (JIException e) {
            e.printStackTrace();
            if (m_Session != null) {
                try {
                    JISession.destroySession(m_Session);
                } catch (JIException e1) {
                    logger.error(e.getMessage(), e);
                }
            }
        } catch (UnknownHostException e) {
            if (m_Session != null) {
                try {
                    JISession.destroySession(m_Session);
                } catch (JIException e1) {
                    logger.error(e.getMessage(), e);
                }
            }
        }
    }

    public void disconnect() {
        try {
            JISession.destroySession(m_Session);
        } catch (JIException e) {
            logger.error(e.getMessage(), e);
        }
    }


    public static void main(String[] args) {

        WmiService wmiService = new WmiService("172.16.158.129");

        //域(一般为空字符),用户名,密码
        wmiService.connect("", "username", "password");

        //系统信息
        wmiService.query("SELECT * FROM Win32_ComputerSystem");

        //CPU信息
        wmiService.query("SELECT * FROM Win32_PerfFormattedData_PerfOS_Processor WHERE Name != '_Total'");

        //内存信息
        wmiService.query("SELECT * FROM Win32_PerfFormattedData_PerfOS_Memory");

        //磁盘信息
        wmiService.query("SELECT * FROM Win32_PerfRawData_PerfDisk_PhysicalDisk Where Name != '_Total'");

        wmiService.disconnect();
    }
}

mavne配置(pom.xml)
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.noahx</groupId>
    <artifactId>wmi-test</artifactId>
    <version>1.0</version>


    <dependencies>

        <dependency>
            <groupId>org.kohsuke.jinterop</groupId>
            <artifactId>j-interop</artifactId>
            <version>2.0.8-kohsuke-1</version>
        </dependency>

        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>1.6.4</version>
        </dependency>

    </dependencies>
    
</project>

运行结果
query:SELECT * FROM Win32_ComputerSystem
(0):

instance of Win32_ComputerSystem
{
	AdminPasswordStatus = 1;
	AutomaticResetBootOption = FALSE;
	AutomaticResetCapability = TRUE;
	BootOptionOnLimit = 3;
	BootOptionOnWatchDog = 3;
	BootROMSupported = TRUE;
	BootupState = "Normal boot";
	Caption = "NAK-E1A7C21EA3C";
	ChassisBootupState = 3;
	CreationClassName = "Win32_ComputerSystem";
	CurrentTimeZone = 480;
	Description = "AT/AT COMPATIBLE";
	Domain = "WORKGROUP";
	DomainRole = 0;
	EnableDaylightSavingsTime = TRUE;
	FrontPanelResetStatus = 3;
	InfraredSupported = FALSE;
	KeyboardPasswordStatus = 3;
	Manufacturer = "VMware, Inc.";
	Model = "VMware Virtual Platform";
	Name = "NAK-E1A7C21EA3C";
	NetworkServerModeEnabled = TRUE;
	NumberOfLogicalProcessors = 2;
	NumberOfProcessors = 1;
	OEMStringArray = {"[MS_VM_CERT/SHA1/27d66596a61c48dd3dc7216fd715126e33f59ae7]", "Welcome to the Virtual Machine"};
	PartOfDomain = FALSE;
	PauseAfterReset = "3932100000";
	PowerOnPasswordStatus = 0;
	PowerState = 0;
	PowerSupplyState = 3;
	PrimaryOwnerName = "nak";
	ResetCapability = 1;
	ResetCount = -1;
	ResetLimit = -1;
	Roles = {"LM_Workstation", "LM_Server", "NT", "Potential_Browser", "Master_Browser"};
	Status = "OK";
	SystemStartupDelay = 0;
	SystemStartupOptions = {"\"Microsoft Windows XP Professional\" /noexecute=optin /fastdetect"};
	SystemStartupSetting = 0;
	SystemType = "X86-based PC";
	ThermalState = 3;
	TotalPhysicalMemory = "1610063872";
	UserName = "NAK-E1A7C21EA3C\\a";
	WakeUpType = 6;
};


query:SELECT * FROM Win32_PerfFormattedData_PerfOS_Processor WHERE Name != '_Total'
(0):

instance of Win32_PerfFormattedData_PerfOS_Processor
{
	C1TransitionsPersec = "77";
	C2TransitionsPersec = "0";
	C3TransitionsPersec = "0";
	DPCRate = 0;
	DPCsQueuedPersec = 4;
	InterruptsPersec = 71;
	Name = "0";
	PercentC1Time = "96";
	PercentC2Time = "0";
	PercentC3Time = "0";
	PercentDPCTime = "0";
	PercentIdleTime = "100";
	PercentInterruptTime = "0";
	PercentPrivilegedTime = "0";
	PercentProcessorTime = "0";
	PercentUserTime = "0";
};


(1):

instance of Win32_PerfFormattedData_PerfOS_Processor
{
	C1TransitionsPersec = "83";
	C2TransitionsPersec = "0";
	C3TransitionsPersec = "0";
	DPCRate = 0;
	DPCsQueuedPersec = 10;
	InterruptsPersec = 67;
	Name = "1";
	PercentC1Time = "96";
	PercentC2Time = "0";
	PercentC3Time = "0";
	PercentDPCTime = "0";
	PercentIdleTime = "100";
	PercentInterruptTime = "0";
	PercentPrivilegedTime = "0";
	PercentProcessorTime = "0";
	PercentUserTime = "0";
};


query:SELECT * FROM Win32_PerfFormattedData_PerfOS_Memory
(0):

instance of Win32_PerfFormattedData_PerfOS_Memory
{
	AvailableBytes = "1142099968";
	AvailableKBytes = "1115332";
	AvailableMBytes = "1089";
	CacheBytes = "70725632";
	CacheBytesPeak = "72904704";
	CacheFaultsPersec = 634;
	CommitLimit = "3063078912";
	CommittedBytes = "326488064";
	DemandZeroFaultsPersec = 13965;
	FreeSystemPageTableEntries = 159743;
	PageFaultsPersec = 13965;
	PageReadsPersec = 0;
	PagesInputPersec = 0;
	PagesOutputPersec = 0;
	PagesPersec = 0;
	PageWritesPersec = 0;
	PercentCommittedBytesInUse = 10;
	PoolNonpagedAllocs = 38040;
	PoolNonpagedBytes = "7585792";
	PoolPagedAllocs = 57820;
	PoolPagedBytes = "29380608";
	PoolPagedResidentBytes = "28622848";
	SystemCacheResidentBytes = "40235008";
	SystemCodeResidentBytes = "1867776";
	SystemCodeTotalBytes = "1167360";
	SystemDriverResidentBytes = "0";
	SystemDriverTotalBytes = "4071424";
	TransitionFaultsPersec = 0;
	WriteCopiesPersec = 0;
};


query:SELECT * FROM Win32_PerfRawData_PerfDisk_PhysicalDisk Where Name != '_Total'
(0):

instance of Win32_PerfRawData_PerfDisk_PhysicalDisk
{
	AvgDiskBytesPerRead = "138920448";
	AvgDiskBytesPerRead_Base = 8000;
	AvgDiskBytesPerTransfer = "208285696";
	AvgDiskBytesPerTransfer_Base = 13701;
	AvgDiskBytesPerWrite = "69365248";
	AvgDiskBytesPerWrite_Base = 5701;
	AvgDiskQueueLength = "581460650";
	AvgDiskReadQueueLength = "405581626";
	AvgDisksecPerRead = 2794786622;
	AvgDisksecPerRead_Base = 8000;
	AvgDisksecPerTransfer = 322083534;
	AvgDisksecPerTransfer_Base = 13701;
	AvgDisksecPerWrite = 1822264208;
	AvgDisksecPerWrite_Base = 5701;
	AvgDiskWriteQueueLength = "175879024";
	CurrentDiskQueueLength = 0;
	DiskBytesPersec = "208285696";
	DiskReadBytesPersec = "138920448";
	DiskReadsPersec = 8000;
	DiskTransfersPersec = 13701;
	DiskWriteBytesPersec = "69365248";
	DiskWritesPersec = 5701;
	Frequency_Object = "0";
	Frequency_PerfTime = "3034010000";
	Frequency_Sys100NS = "10000000";
	Name = "0 C:";
	PercentDiskReadTime = "405581626";
	PercentDiskReadTime_Base = "129895856572522792";
	PercentDiskTime = "581460650";
	PercentDiskTime_Base = "129895856572522792";
	PercentDiskWriteTime = "175879024";
	PercentDiskWriteTime_Base = "129895856572522792";
	PercentIdleTime = "18446744072967667781";
	PercentIdleTime_Base = "129895856572522792";
	SplitIOPerSec = 1074;
	Timestamp_Object = "0";
	Timestamp_PerfTime = "3635534093651";
	Timestamp_Sys100NS = "129895856572522792";
}; 


3、有可能出现的问题

报错a
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 org.noah.wmitest.WmiService.connect(WmiService.java:122)
	at org.noah.wmitest.WmiService.main(WmiService.java:177)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
	at java.lang.reflect.Method.invoke(Method.java:597)
	at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)
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:105)
	at rpc.Stub.call(Stub.java:110)
	at org.jinterop.winreg.smb.JIWinRegStub.winreg_OpenHKLM(JIWinRegStub.java:113)
	... 10 more

需要开启Remote Registry服务

报错b
org.jinterop.dcom.common.JIException: Message not found for errorCode: 0xC0000001
	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 org.noah.wmitest.WmiService.connect(WmiService.java:87)
	at org.noah.wmitest.WmiService.main(WmiService.java:142)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
	at java.lang.reflect.Method.invoke(Method.java:597)
	at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)
Caused by: jcifs.smb.SmbException: Connection timeout
jcifs.util.transport.TransportException: Connection timeout

或

org.jinterop.dcom.common.JIException: Message not found for errorCode: 0x8001FFFF
	at org.jinterop.dcom.core.JIComServer.init(JIComServer.java:576)
	at org.jinterop.dcom.core.JIComServer.initialise(JIComServer.java:481)
	at org.jinterop.dcom.core.JIComServer.<init>(JIComServer.java:414)
	at org.noah.wmitest.WmiService.connect(WmiService.java:87)
	at org.noah.wmitest.WmiService.main(WmiService.java:142)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
	at java.lang.reflect.Method.invoke(Method.java:597)
	at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)
Caused by: java.net.ConnectException: Connection timed out

需要禁用放火墙

4、总结

j-Interop纯java跨平台,我就是linux系统。
用j-Interop就可以很方便的调用windows系统com,虽然这里只演示了WMI。
如果关心WMI与监控的话,建议去opennms-wmi看一看,他们有更好api封装(底层也是j-Interop)。

© 著作权归作者所有

NoahX
粉丝 136
博文 59
码字总数 48419
作品 0
海淀
程序员
私信 提问
加载中

评论(11)

追梦人686
xp 上面出现 JIException:Access is denied,怎么解决,首先我的密码没有问题,remote regist 和WMI 都已经开了,防火墙也关了,经典模式也设置了,就是报这个错,怎么解决呢?
NoahX
NoahX 博主

引用来自“java一份子”的评论

java如果通过该协议执行cmd命令,如果有,请给个答案,项目本来是c语言写的,但是目前改为java写
不可以,只能是WMI Query。你需求可以使用WinRM协议。我有样例 http://pan.baidu.com/s/1WJlQu
java一份子
java一份子
java如果通过该协议执行cmd命令,如果有,请给个答案,项目本来是c语言写的,但是目前改为java写
java一份子
java一份子
可以执行cmd命令吗
NoahX
NoahX 博主

引用来自“izee”的评论

查询当前系统可不可以免认证?
DCom,不像标准的 COm。我并没有试过但感觉必须要凭证,因为这种方式近似看作一次远程调用。
izee
izee
查询当前系统可不可以免认证?
黄金比

引用来自“肖国颖”的评论

引用来自“黄金比”的评论

不知道远程调用行不行呢?请博主明确一下。

你指的是非本机吗?我测试的方式就是一台linux运行程序指定ip调用另一台win服务器的wmi

收到,谢博主,试下先!
NoahX
NoahX 博主

引用来自“黄金比”的评论

不知道远程调用行不行呢?请博主明确一下。

你指的是非本机吗?我测试的方式就是一台linux运行程序指定ip调用另一台win服务器的wmi
黄金比
不知道远程调用行不行呢?请博主明确一下。
明月惊鹊
明月惊鹊
WMI里应该就有控制防火墙的。这种操作肯定需要管理员权限了。
100%纯java调用windows的wmi获取监控数据

纯java主要体现在可以跨平台调用com。所用的是j-Interop,它是100%纯java实现的com的调用 1、环境准备 a、windows要开启Remote Registry与Windows Management Instrumentation服务 b、修改安...

石海龙
2012/08/16
948
0
QT还有前途吗?迷茫中....

所谓的跨平台,windows有注册表、服务、WMI,这些QT本身都无法实现,如果调用系统API又无法跨平台,况且资源过少,都是MFC实例,如果想看懂WMI,又得学MFC,而学会了MFC,windows平台就没必要...

Pwarn
2015/08/29
5.4K
14
Berkeley DB数据库学习1

BDB使用教程 Berkeley DB是历史悠久的嵌入式数据库系统,在06年被 Oracle 收购了。现在我们在 Oracle 网站上会看到: BerkeleyDB、BerkeleyDB XML 和 BerkeleyDB JAVA Edition 这个三个东东。...

月下独酌100
2013/02/17
362
0
Java调用wmi执行dos命令

如题,我在网上找了一段代码,是java调用wmi的,但是这代码只能监控主机状态,查看了api也没有找到能执行dos命令得方法,请问调用wmi后是否可以执行dos命令?如果可以,请大神明示。 最后有个...

一身正气
2015/01/14
1K
3
JRuby 1.4 发布

JRuby 1.4.0发布了!JRuby是Ruby编程语言的100%纯Java实现,它结合了Ruby简洁的语法以及Java丰富的类库。 重要特性: 新的YAML分析器 改进了对java集成的支持 Windows安装程序 新的嵌入式框架...

红薯
2009/11/12
237
0

没有更多内容

加载失败,请刷新页面

加载更多

是否有内置功能可以打印对象的所有当前属性和值?

所以我在这里寻找的是类似PHP的print_r函数。 这样一来,我可以通过查看问题对象的状态来调试脚本。 #1楼 可能值得一看- 是否有与Perl的Data :: Dumper等效的Python? 我的建议是 https://gi...

技术盛宴
28分钟前
5
0
直击面试,聊聊 GC 机制

前言 文章来源:https://studyidea.cn/ GC 中文直译垃圾回收,是一种回收内存空间避免内存泄漏的机制。当 JVM 内存紧张,通过执行 GC 有效回收内存,转而分配给新对象从而实现内存的再利用。 ...

程序通事
31分钟前
4
0
Mybatis where 1=1 和 标签

在mybatis中拼接查询语句,偶尔会出现where后面可能一个字段的值都没有,就导致所有条件无效,导致where没有存在的意义;但也有可能这些条件会存在。那解决这个问题的方法,最常见的就是: ...

观海562
33分钟前
4
0
git常用初始化设置

日志编辑工具 git config --global core.editor vim ssh访问 cd /home/weiguangyue/.sshssh-keygen -t rsa -C weiyue888999@126.com 提交者信息用户名 git config --global user.nam......

萧默
34分钟前
4
0
面试题-关于Java线程池一篇文章就够了

在Java面试中,线程池相关知识,虽不能说是必问提,但出现的频次也是非常高的。同时又鉴于公众号“程序新视界”的读者后台留言让写一篇关于Java线程池的文章,于是就有本篇内容,本篇将基于J...

程序新视界
38分钟前
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部