纯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
1 | SetACL.exe -on "HKEY_CLASSES_ROOT\CLSID\{76A64158-CB41-11D1-8B02-00600806D9B6}" -ot reg -actn setowner -ownr "n:Administrators" |
2 | 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类
001 | package org.noah.wmitest; |
003 | import org.jinterop.dcom.common.JIException; |
004 | import org.jinterop.dcom.common.JISystem; |
005 | import org.jinterop.dcom.core.*; |
006 | import org.jinterop.dcom.impls.JIObjectFactory; |
007 | import org.jinterop.dcom.impls.automation.IJIDispatch; |
008 | import org.jinterop.dcom.impls.automation.IJIEnumVariant; |
009 | import org.slf4j.Logger; |
010 | import org.slf4j.LoggerFactory; |
012 | import java.net.UnknownHostException; |
013 | import java.util.logging.Level; |
016 | * Created with IntelliJ IDEA. |
020 | * To change this template use File | Settings | File Templates. |
022 | public class WmiService { |
024 | private JIComServer m_ComStub = null ; |
025 | private IJIComObject m_ComObject = null ; |
026 | private IJIDispatch m_Dispatch = null ; |
027 | private String m_Address = null ; |
028 | private JISession m_Session = null ; |
029 | private IJIDispatch m_WbemServices = null ; |
031 | private static final String WMI_CLSID = "76A6415B-CB41-11d1-8B02-00600806D9B6" ; |
032 | private static final String WMI_PROGID = "WbemScripting.SWbemLocator" ; |
034 | private Logger logger = LoggerFactory.getLogger( this .getClass()); |
037 | public WmiService(String address) { |
038 | JISystem.setAutoRegisteration( true ); |
039 | JISystem.getLogger().setLevel(Level.WARNING); |
043 | public void query(String strQuery) { |
045 | System.out.println( "query:" + strQuery); |
047 | JIVariant results[] = new JIVariant[ 0 ]; |
049 | results = m_WbemServices.callMethodA( "ExecQuery" , new Object[]{ new JIString(strQuery), JIVariant.OPTIONAL_PARAM(), JIVariant.OPTIONAL_PARAM(), JIVariant.OPTIONAL_PARAM()}); |
050 | IJIDispatch wOSd = (IJIDispatch) JIObjectFactory.narrowObject((results[ 0 ]).getObjectAsComObject()); |
052 | int count = wOSd.get( "Count" ).getObjectAsInt(); |
054 | IJIComObject enumComObject = wOSd.get( "_NewEnum" ).getObjectAsComObject(); |
055 | IJIEnumVariant enumVariant = (IJIEnumVariant) JIObjectFactory.narrowObject(enumComObject.queryInterface(IJIEnumVariant.IID)); |
057 | IJIDispatch wbemObject_dispatch = null ; |
059 | for ( int c = 0 ; c < count; c++) { |
061 | Object[] values = enumVariant.next( 1 ); |
062 | JIArray array = (JIArray) values[ 0 ]; |
063 | Object[] arrayObj = (Object[]) array.getArrayInstance(); |
064 | for ( int j = 0 ; j < arrayObj.length; j++) { |
065 | wbemObject_dispatch = (IJIDispatch) JIObjectFactory.narrowObject(((JIVariant) arrayObj[j]).getObjectAsComObject()); |
068 | String str = (wbemObject_dispatch.callMethodA( "GetObjectText_" , new Object[]{ 1 }))[ 0 ].getObjectAsString2(); |
069 | System.out.println( "(" + c + "):" ); |
070 | System.out.println(str); |
071 | System.out.println(); |
075 | } catch (JIException e) { |
080 | public void connect( final String domain, final String username, final String password) { |
083 | m_Session = JISession.createSession(domain, username, password); |
084 | m_Session.useSessionSecurity( true ); |
085 | m_Session.setGlobalSocketTimeout( 5000 ); |
087 | m_ComStub = new JIComServer(JIProgId.valueOf(WMI_PROGID), m_Address, m_Session); |
089 | IJIComObject unknown = m_ComStub.createInstance(); |
090 | m_ComObject = unknown.queryInterface(WMI_CLSID); |
092 | m_Dispatch = (IJIDispatch) JIObjectFactory.narrowObject(m_ComObject.queryInterface(IJIDispatch.IID)); |
093 | JIVariant results[] = m_Dispatch.callMethodA( |
096 | new JIString(m_Address), |
097 | JIVariant.OPTIONAL_PARAM(), |
098 | JIVariant.OPTIONAL_PARAM(), |
099 | JIVariant.OPTIONAL_PARAM(), |
100 | JIVariant.OPTIONAL_PARAM(), |
101 | JIVariant.OPTIONAL_PARAM(), |
103 | JIVariant.OPTIONAL_PARAM() |
107 | m_WbemServices = (IJIDispatch) JIObjectFactory.narrowObject((results[ 0 ]).getObjectAsComObject()); |
109 | } catch (JIException e) { |
111 | if (m_Session != null ) { |
113 | JISession.destroySession(m_Session); |
114 | } catch (JIException e1) { |
115 | logger.error(e.getMessage(), e); |
118 | } catch (UnknownHostException e) { |
119 | if (m_Session != null ) { |
121 | JISession.destroySession(m_Session); |
122 | } catch (JIException e1) { |
123 | logger.error(e.getMessage(), e); |
129 | public void disconnect() { |
131 | JISession.destroySession(m_Session); |
132 | } catch (JIException e) { |
133 | logger.error(e.getMessage(), e); |
138 | public static void main(String[] args) { |
140 | WmiService wmiService = new WmiService( "172.16.158.129" ); |
143 | wmiService.connect( "" , "username" , "password" ); |
146 | wmiService.query( "SELECT * FROM Win32_ComputerSystem" ); |
149 | wmiService.query( "SELECT * FROM Win32_PerfFormattedData_PerfOS_Processor WHERE Name != '_Total'" ); |
152 | wmiService.query( "SELECT * FROM Win32_PerfFormattedData_PerfOS_Memory" ); |
155 | wmiService.query( "SELECT * FROM Win32_PerfRawData_PerfDisk_PhysicalDisk Where Name != '_Total'" ); |
157 | wmiService.disconnect(); |
mavne配置(pom.xml)
01 | <? xml version = "1.0" encoding = "UTF-8" ?> |
02 | < project xmlns = "http://maven.apache.org/POM/4.0.0" |
03 | xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance" |
04 | xsi:schemaLocation = "http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" > |
05 | < modelVersion >4.0.0</ modelVersion > |
07 | < groupId >org.noahx</ groupId > |
08 | < artifactId >wmi-test</ artifactId > |
09 | < version >1.0</ version > |
15 | < groupId >org.kohsuke.jinterop</ groupId > |
16 | < artifactId >j-interop</ artifactId > |
17 | < version >2.0.8-kohsuke-1</ version > |
21 | < groupId >org.slf4j</ groupId > |
22 | < artifactId >slf4j-log4j12</ artifactId > |
23 | < version >1.6.4</ version > |
运行结果
001 | query:SELECT * FROM Win32_ComputerSystem |
004 | instance of Win32_ComputerSystem |
006 | AdminPasswordStatus = 1; |
007 | AutomaticResetBootOption = FALSE; |
008 | AutomaticResetCapability = TRUE; |
009 | BootOptionOnLimit = 3; |
010 | BootOptionOnWatchDog = 3; |
011 | BootROMSupported = TRUE; |
012 | BootupState = "Normal boot" ; |
013 | Caption = "NAK-E1A7C21EA3C" ; |
014 | ChassisBootupState = 3; |
015 | CreationClassName = "Win32_ComputerSystem" ; |
016 | CurrentTimeZone = 480; |
017 | Description = "AT/AT COMPATIBLE" ; |
018 | Domain = "WORKGROUP" ; |
020 | EnableDaylightSavingsTime = TRUE; |
021 | FrontPanelResetStatus = 3; |
022 | InfraredSupported = FALSE; |
023 | KeyboardPasswordStatus = 3; |
024 | Manufacturer = "VMware, Inc." ; |
025 | Model = "VMware Virtual Platform" ; |
026 | Name = "NAK-E1A7C21EA3C" ; |
027 | NetworkServerModeEnabled = TRUE; |
028 | NumberOfLogicalProcessors = 2; |
029 | NumberOfProcessors = 1; |
030 | OEMStringArray = { "[MS_VM_CERT/SHA1/27d66596a61c48dd3dc7216fd715126e33f59ae7]" , "Welcome to the Virtual Machine" }; |
031 | PartOfDomain = FALSE; |
032 | PauseAfterReset = "3932100000" ; |
033 | PowerOnPasswordStatus = 0; |
035 | PowerSupplyState = 3; |
036 | PrimaryOwnerName = "nak" ; |
040 | Roles = { "LM_Workstation" , "LM_Server" , "NT" , "Potential_Browser" , "Master_Browser" }; |
042 | SystemStartupDelay = 0; |
043 | SystemStartupOptions = { "\"Microsoft Windows XP Professional\" /noexecute=optin /fastdetect" }; |
044 | SystemStartupSetting = 0; |
045 | SystemType = "X86-based PC" ; |
047 | TotalPhysicalMemory = "1610063872" ; |
048 | UserName = "NAK-E1A7C21EA3C\\a" ; |
053 | query:SELECT * FROM Win32_PerfFormattedData_PerfOS_Processor WHERE Name != '_Total' |
056 | instance of Win32_PerfFormattedData_PerfOS_Processor |
058 | C1TransitionsPersec = "77" ; |
059 | C2TransitionsPersec = "0" ; |
060 | C3TransitionsPersec = "0" ; |
062 | DPCsQueuedPersec = 4; |
063 | InterruptsPersec = 71; |
065 | PercentC1Time = "96" ; |
068 | PercentDPCTime = "0" ; |
069 | PercentIdleTime = "100" ; |
070 | PercentInterruptTime = "0" ; |
071 | PercentPrivilegedTime = "0" ; |
072 | PercentProcessorTime = "0" ; |
073 | PercentUserTime = "0" ; |
079 | instance of Win32_PerfFormattedData_PerfOS_Processor |
081 | C1TransitionsPersec = "83" ; |
082 | C2TransitionsPersec = "0" ; |
083 | C3TransitionsPersec = "0" ; |
085 | DPCsQueuedPersec = 10; |
086 | InterruptsPersec = 67; |
088 | PercentC1Time = "96" ; |
091 | PercentDPCTime = "0" ; |
092 | PercentIdleTime = "100" ; |
093 | PercentInterruptTime = "0" ; |
094 | PercentPrivilegedTime = "0" ; |
095 | PercentProcessorTime = "0" ; |
096 | PercentUserTime = "0" ; |
100 | query:SELECT * FROM Win32_PerfFormattedData_PerfOS_Memory |
103 | instance of Win32_PerfFormattedData_PerfOS_Memory |
105 | AvailableBytes = "1142099968" ; |
106 | AvailableKBytes = "1115332" ; |
107 | AvailableMBytes = "1089" ; |
108 | CacheBytes = "70725632" ; |
109 | CacheBytesPeak = "72904704" ; |
110 | CacheFaultsPersec = 634; |
111 | CommitLimit = "3063078912" ; |
112 | CommittedBytes = "326488064" ; |
113 | DemandZeroFaultsPersec = 13965; |
114 | FreeSystemPageTableEntries = 159743; |
115 | PageFaultsPersec = 13965; |
117 | PagesInputPersec = 0; |
118 | PagesOutputPersec = 0; |
120 | PageWritesPersec = 0; |
121 | PercentCommittedBytesInUse = 10; |
122 | PoolNonpagedAllocs = 38040; |
123 | PoolNonpagedBytes = "7585792" ; |
124 | PoolPagedAllocs = 57820; |
125 | PoolPagedBytes = "29380608" ; |
126 | PoolPagedResidentBytes = "28622848" ; |
127 | SystemCacheResidentBytes = "40235008" ; |
128 | SystemCodeResidentBytes = "1867776" ; |
129 | SystemCodeTotalBytes = "1167360" ; |
130 | SystemDriverResidentBytes = "0" ; |
131 | SystemDriverTotalBytes = "4071424" ; |
132 | TransitionFaultsPersec = 0; |
133 | WriteCopiesPersec = 0; |
137 | query:SELECT * FROM Win32_PerfRawData_PerfDisk_PhysicalDisk Where Name != '_Total' |
140 | instance of Win32_PerfRawData_PerfDisk_PhysicalDisk |
142 | AvgDiskBytesPerRead = "138920448" ; |
143 | AvgDiskBytesPerRead_Base = 8000; |
144 | AvgDiskBytesPerTransfer = "208285696" ; |
145 | AvgDiskBytesPerTransfer_Base = 13701; |
146 | AvgDiskBytesPerWrite = "69365248" ; |
147 | AvgDiskBytesPerWrite_Base = 5701; |
148 | AvgDiskQueueLength = "581460650" ; |
149 | AvgDiskReadQueueLength = "405581626" ; |
150 | AvgDisksecPerRead = 2794786622; |
151 | AvgDisksecPerRead_Base = 8000; |
152 | AvgDisksecPerTransfer = 322083534; |
153 | AvgDisksecPerTransfer_Base = 13701; |
154 | AvgDisksecPerWrite = 1822264208; |
155 | AvgDisksecPerWrite_Base = 5701; |
156 | AvgDiskWriteQueueLength = "175879024" ; |
157 | CurrentDiskQueueLength = 0; |
158 | DiskBytesPersec = "208285696" ; |
159 | DiskReadBytesPersec = "138920448" ; |
160 | DiskReadsPersec = 8000; |
161 | DiskTransfersPersec = 13701; |
162 | DiskWriteBytesPersec = "69365248" ; |
163 | DiskWritesPersec = 5701; |
164 | Frequency_Object = "0" ; |
165 | Frequency_PerfTime = "3034010000" ; |
166 | Frequency_Sys100NS = "10000000" ; |
168 | PercentDiskReadTime = "405581626" ; |
169 | PercentDiskReadTime_Base = "129895856572522792" ; |
170 | PercentDiskTime = "581460650" ; |
171 | PercentDiskTime_Base = "129895856572522792" ; |
172 | PercentDiskWriteTime = "175879024" ; |
173 | PercentDiskWriteTime_Base = "129895856572522792" ; |
174 | PercentIdleTime = "18446744072967667781" ; |
175 | PercentIdleTime_Base = "129895856572522792" ; |
176 | SplitIOPerSec = 1074; |
177 | Timestamp_Object = "0" ; |
178 | Timestamp_PerfTime = "3635534093651" ; |
179 | Timestamp_Sys100NS = "129895856572522792" ; |
180 | };<span style= "font-family:'sans serif, tahoma, verdana, helvetica';font-size:x-small;" ><span style= "line-height:18.18181800842285px;white-space:normal;" > </span></span> |
3、有可能出现的问题
报错a
01 | org.jinterop.dcom.common.JIException: Message not found for errorCode: 0xC0000034 |
02 | at org.jinterop.winreg.smb.JIWinRegStub.winreg_OpenHKLM(JIWinRegStub.java: 115 ) |
03 | at org.jinterop.dcom.core.JIProgId.getIdFromWinReg(JIProgId.java: 130 ) |
04 | at org.jinterop.dcom.core.JIProgId.getCorrespondingCLSID(JIProgId.java: 162 ) |
05 | at org.jinterop.dcom.core.JIComServer.<init>(JIComServer.java: 413 ) |
06 | at org.noah.wmitest.WmiService.connect(WmiService.java: 122 ) |
07 | at org.noah.wmitest.WmiService.main(WmiService.java: 177 ) |
08 | at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) |
09 | at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java: 39 ) |
10 | at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java: 25 ) |
11 | at java.lang.reflect.Method.invoke(Method.java: 597 ) |
12 | at com.intellij.rt.execution.application.AppMain.main(AppMain.java: 120 ) |
13 | Caused by: jcifs.smb.SmbException: The system cannot find the file specified. |
14 | at jcifs.smb.SmbTransport.checkStatus(SmbTransport.java: 522 ) |
15 | at jcifs.smb.SmbTransport.send(SmbTransport.java: 622 ) |
16 | at jcifs.smb.SmbSession.send(SmbSession.java: 239 ) |
17 | at jcifs.smb.SmbTree.send(SmbTree.java: 109 ) |
18 | at jcifs.smb.SmbFile.send(SmbFile.java: 718 ) |
19 | at jcifs.smb.SmbFile.open0(SmbFile.java: 923 ) |
20 | at jcifs.smb.SmbFile.open(SmbFile.java: 940 ) |
21 | at jcifs.smb.SmbFileOutputStream.<init>(SmbFileOutputStream.java: 142 ) |
22 | at jcifs.smb.TransactNamedPipeOutputStream.<init>(TransactNamedPipeOutputStream.java: 32 ) |
23 | at jcifs.smb.SmbNamedPipe.getNamedPipeOutputStream(SmbNamedPipe.java: 187 ) |
24 | at rpc.ncacn_np.RpcTransport.attach(RpcTransport.java: 92 ) |
25 | at rpc.Stub.attach(Stub.java: 105 ) |
26 | at rpc.Stub.call(Stub.java: 110 ) |
27 | at org.jinterop.winreg.smb.JIWinRegStub.winreg_OpenHKLM(JIWinRegStub.java: 113 ) |
需要开启Remote Registry服务
报错b
01 | org.jinterop.dcom.common.JIException: Message not found for errorCode: 0xC0000001 |
02 | at org.jinterop.winreg.smb.JIWinRegStub.winreg_OpenHKLM(JIWinRegStub.java: 115 ) |
03 | at org.jinterop.dcom.core.JIProgId.getIdFromWinReg(JIProgId.java: 130 ) |
04 | at org.jinterop.dcom.core.JIProgId.getCorrespondingCLSID(JIProgId.java: 162 ) |
05 | at org.jinterop.dcom.core.JIComServer.<init>(JIComServer.java: 413 ) |
06 | at org.noah.wmitest.WmiService.connect(WmiService.java: 87 ) |
07 | at org.noah.wmitest.WmiService.main(WmiService.java: 142 ) |
08 | at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) |
09 | at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java: 39 ) |
10 | at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java: 25 ) |
11 | at java.lang.reflect.Method.invoke(Method.java: 597 ) |
12 | at com.intellij.rt.execution.application.AppMain.main(AppMain.java: 120 ) |
13 | Caused by: jcifs.smb.SmbException: Connection timeout |
14 | jcifs.util.transport.TransportException: Connection timeout |
18 | org.jinterop.dcom.common.JIException: Message not found for errorCode: 0x8001FFFF |
19 | at org.jinterop.dcom.core.JIComServer.init(JIComServer.java: 576 ) |
20 | at org.jinterop.dcom.core.JIComServer.initialise(JIComServer.java: 481 ) |
21 | at org.jinterop.dcom.core.JIComServer.<init>(JIComServer.java: 414 ) |
22 | at org.noah.wmitest.WmiService.connect(WmiService.java: 87 ) |
23 | at org.noah.wmitest.WmiService.main(WmiService.java: 142 ) |
24 | at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) |
25 | at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java: 39 ) |
26 | at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java: 25 ) |
27 | at java.lang.reflect.Method.invoke(Method.java: 597 ) |
28 | at com.intellij.rt.execution.application.AppMain.main(AppMain.java: 120 ) |
29 | Caused by: java.net.ConnectException: Connection timed out |
需要禁用放火墙
4、总结
j-Interop纯java跨平台,我就是linux系统。
用j-Interop就可以很方便的调用windows系统com,虽然这里只演示了WMI。
如果关心WMI与监控的话,建议去opennms-wmi看一看,他们有更好api封装(底层也是j-Interop)。