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

纯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)。

转载于:https://my.oschina.net/noahxiao/blog/73163

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值