Windows Management Instrumentation (WMI) from Java

This post shows how to instrument Windows resources using WMI and Java. The attached source code has 3 programs:

  1. PrintInstances.java prints all instances of a given class. For e.g., to retrieve a list of services use Win32_Service in WML.
  2. SimpleServiceManager.java starts or stops a given service.
  3. ServiceManager.java starts or stops a service by starting/stopping any dependents.

Windows Management Instrumentation (WMI) is used to access management information and instrument resources of a Windows machine. What makes it interesting is that with WMI, you can manage/control components on a Windows machine remotely. Some knowledge of DCOM is helpful as WMI connections are made through DCOM.

This post shows how to instrument Windows resources using WMI and Java. Let’s say, you’d like to program starting and stopping services (like SQL Server service, Web Server service etc.,) on a remote machine. Here are some tools that can be used for this purpose:


Tool Pros Cons License
j-interop
  • Open source
  • It’s free (no cost)
  • 100% Java. So it works on any platform.
  • None. The only thing I would say is that the API is just a bit verbose (compared to say JACOB).
LGPL
JACOB project
  • Open source
  • It’s free (no cost)
  • Simple API, programs are shorter
  • It uses JNI and loads DLL(s), so works only on windows machines.
LGPL
j-integra
  • Available for Windows and other platforms
  • Nice clean API
  • Good documentation
  • You have to generate com2java proxies and mess around with DLLs
Commercial. May cost anywhere from $400 to $8000

My choice is j-interop. The following program in Java uses j-interop library to start/stop services on a remote Windows machine. You can run the program from a Linux machine as j-interop is 100% Java.

WMI in action

This code snippet from MSDN written in VBScript using WMI Scripting Library shows how to retrieve services and stop them.

strComputer = "."
strNamespace = "\root\cimv2"
strClass = "Win32_Service"

Const wbemFlagReturnImmediately = &h10
Const wbemFlagForwardOnly = &h20

Set objSWbemServices = GetObject("winmgmts:\\" & strComputer & strNamespace)
Set colSWbemObjectSet = objSWbemServices.ExecQuery("SELECT * FROM " & strClass, _
                        "WQL" _
                        wbemFlagReturnImmediately + wbemFlagForwardOnly)

For Each objSWbemObject in colSWbemObjectSet
     objSWbemObject.StopService()
Next

WMI Scripting Library Object Model (Fig 1)

WMI Scripting Library Object Model (Fig 1)

WMI Scripting Library is single DLL wbemdisp.dll that physically resides in the %SystemRoot%\system32\wbem directory. The library provides a unified object model and a simple API to manage and instrument Windows resources. By that I mean, all resources that can be instrumented, can be managed using the same steps.

The following figure (Fig 1) shows WMI Scripting Library Object Model. The model also shows the sequence of steps to be performed to get hold of a particular resource. Let’s go through the steps one at a time.

Step 1

As you can see from the object model, the first step is to connect to WMI service on the target machine. There are 2 ways to connect to WMI:

  1. Through WMI moniker

    			strComputer = "."
    			strNamespace = "\root\cimv2"
    			Set objSWbemServices = GetObject("winmgmts:\\" & strComputer & strNamespace)
    			
  2. Through SWbemLocator object

    			strComputer = "."
    			strNamespace = "\root\cimv2"
    			Set objSWbemLocator = CreateObject("WbemScripting.SWbemLocator")
    			Set objSWbemServices = objLocator.ConnectServer(strComputer, strNamespace)
    			

strComputer = "." indicates local machine. To connect to a remote machine, pass the hostname (in addition to username and password).

In Java, using J-Interop you’d write that as:

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

JISession dcomSession = JISession.createSession(domain, user, pass);
JIComServer 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());

The SWbemLocator.ConnectServer method gives us a reference to SWbemServices object that represents a connection to a namespace on either a local computer or a remote host computer. You can then use the methods of the SWbemServices object to access WMI.

Step 2

Once you obtain a reference to the SWbemServices object, you can invoke one of the methods this class exposes depending on what you want to accomplish. For example, to retrieve Windows services, you can invoke SWbemServices.InstancesOf method as show below in VBScript:

Set colSWbemObjectSet = objSWbemServices.InstancesOf("Win32_Service")

In Java (see ListServices.java in the attached source code):

import static org.jinterop.dcom.impls.JIObjectFactory.narrowObject;

params = new Object[] {
		new JIString("Win32_Service"),
		new Integer(0),
		JIVariant.OPTIONAL_PARAM()
};
JIVariant[] servicesSet = wbemServices.callMethodA("InstancesOf", params);
IJIDispatch wbemObjectSet = (IJIDispatch) narrowObject(servicesSet[0].getObjectAsComObject());

The method SWbemServices.InstancesOf returns all instances of a managed resource. To selectively retrieve a subset of resources, you can use the SWbemServices.ExecQuery method which takes a WQL (WMI Query Language) query as shown below.

Const wbemFlagReturnImmediately = &h10
Const wbemFlagForwardOnly = &h20
Set colSWbemObjectSet = objSWbemServices.ExecQuery("SELECT * FROM Win32_Service WHERE State = 'Stopped'", _
                        "WQL" _
                        wbemFlagReturnImmediately + wbemFlagForwardOnly)

In Java that would be:

import static org.jinterop.dcom.impls.JIObjectFactory.narrowObject;

final int RETURN_IMMEDIATE = 0x10;
final int FORWARD_ONLY = 0x20;
params = new Object[] {
		new JIString("SELECT * FROM Win32_Service WHERE State = 'Stopped'"),
		JIVariant.OPTIONAL_PARAM(),
		new JIVariant(new Integer(RETURN_IMMEDIATE + FORWARD_ONLY))
};
JIVariant[] servicesSet = wbemServices.callMethodA("ExecQuery", params);
IJIDispatch wbemObjectSet = (IJIDispatch) narrowObject(servicesSet[0].getObjectAsComObject());

Note that both methods SWbemServices.InstancesOf and SWbemServices.ExecQuery always return a collection of zero or more items represented by SWbemObjectSet object. The wbemFlagReturnImmediately causes the call to return immediately whereas wbemFlagForwardOnly creates a uni-directional iterator.

Step 3

Now the final step. Since our query was to retrieve instances of Win32_Service, each object in the collection returned will be an an object of Win32_Service class. To manage a given service, you just have to invoke the appropriate methods. For example to stop a service in VBScript:

For Each objSWbemObject in colSWbemObjectSet
     objSWbemObject.StopService()
Next

It takes a few more lines in Java:

import static org.jinterop.dcom.impls.JIObjectFactory.narrowObject;

JIVariant newEnumvariant = wbemObjectSet.get("_NewEnum");
IJIComObject enumComObject = newEnumvariant.getObjectAsComObject();
IJIEnumVariant enumVariant = (IJIEnumVariant) narrowObject(enumComObject.queryInterface(IJIEnumVariant.IID));

Object[] elements = enumVariant.next(1);
JIArray aJIArray = (JIArray) elements[0];

JIVariant[] array = (JIVariant[]) aJIArray.getArrayInstance();
for (JIVariant variant : array) {
	IJIDispatch wbemObjectDispatch = (IJIDispatch) narrowObject(variant.getObjectAsComObject());

	JIVariant returnStatus = wbemObjectDispatch.callMethodA("StopService");

	System.out.println(returnStatus.getObjectAsInt());
}

The property _NewEnum is used to enumerate wbemObjectSet collection one object at a time.

Putting it all together

With the 3 steps described above, we can now write a class called SimpleServiceManager that can start and stop a service on a remote machine. Fill in the domain, hostname, username and password and pass service name (not the display name) to start() or stop() a service.

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

import java.util.logging.Level;

import org.jinterop.dcom.common.JISystem;
import org.jinterop.dcom.core.IJIComObject;
import org.jinterop.dcom.core.JIArray;
import org.jinterop.dcom.core.JIComServer;
import org.jinterop.dcom.core.JISession;
import org.jinterop.dcom.core.JIString;
import org.jinterop.dcom.core.JIVariant;
import org.jinterop.dcom.impls.automation.IJIDispatch;
import org.jinterop.dcom.impls.automation.IJIEnumVariant;

/**
 * Manages Windows services using WMI API.
 *
 * @version $Revision: 1.2 $
 * @author $Author: vijaykandy $
 */
public class SimpleServiceManager {

	private static final int STOP = 0;

	private static final int START = 1;

	/**
	 * Driver.
	 *
	 * @param args
	 */
	public static void main(String[] args) {
		String domain = "";
		String hostname = "";
		String username = "";
		String password = "";

		// We'll start 'Event Log' service.
		// Note: Display name is "Event Log" where as service name is "Eventlog"
		SimpleServiceManager manager = new SimpleServiceManager();
		manager.stop(domain, hostname, username, password, "Eventlog");
	}

	/**
	 * Starts a given service if its stopped.
	 *
	 * @param domain
	 * @param hostname
	 * @param username
	 * @param password
	 * @param serviceName
	 */
	public void start(String domain, String hostname, String username, String password, String serviceName) {
		manageService(domain, hostname, username, password, serviceName, START);
	}

	/**
	 * Stops a given service if its running.
	 *
	 * @param domain
	 * @param hostname
	 * @param username
	 * @param password
	 * @param serviceName
	 */
	public void stop(String domain, String hostname, String username, String password, String serviceName) {
		manageService(domain, hostname, username, password, serviceName, STOP);
	}

	/**
	 * Starts/Stops a given service by connecting to the machine identified by
	 * hostname.
	 *
	 *
	 * NOTE: serviceName is the display name of the service.
	 *
	 * @param domain
	 * @param hostname
	 * @param username
	 * @param password
	 * @param serviceName
	 * @param action
	 */
	public void manageService(String domain, String hostname, String username, String password, String serviceName,
			int action) {

		if (action != START && action != STOP) {
			return;
		}

		JISession dcomSession = null;
		try {
			dcomSession = init(domain, username, password);
			JIComServer 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());

			final int RETURN_IMMEDIATE = 0x10;
			final int FORWARD_ONLY = 0x20;
			params = new Object[] {
					new JIString("SELECT * FROM Win32_Service WHERE Name = '" + serviceName + "'"),
					JIVariant.OPTIONAL_PARAM(),
					new JIVariant(new Integer(RETURN_IMMEDIATE + FORWARD_ONLY))
			};
			JIVariant[] servicesSet = wbemServices.callMethodA("ExecQuery", params);
			IJIDispatch wbemObjectSet = (IJIDispatch) narrowObject(servicesSet[0].getObjectAsComObject());

			JIVariant newEnumvariant = wbemObjectSet.get("_NewEnum");
			IJIComObject enumComObject = newEnumvariant.getObjectAsComObject();
			IJIEnumVariant enumVariant = (IJIEnumVariant) narrowObject(enumComObject.queryInterface(IJIEnumVariant.IID));

			Object[] elements = enumVariant.next(1);
			JIArray aJIArray = (JIArray) elements[0];

			JIVariant[] array = (JIVariant[]) aJIArray.getArrayInstance();
			for (JIVariant variant : array) {
				IJIDispatch wbemObjectDispatch = (IJIDispatch) narrowObject(variant.getObjectAsComObject());

				// Print object as text. Optional - comment if not needed
				JIVariant[] v = wbemObjectDispatch.callMethodA("GetObjectText_", new Object[] { 1 });
				System.out.println(v[0].getObjectAsString().getString());

				// Start or Stop the servie
				String methodToInvoke = (action == START) ? "StartService" : "StopService";
				JIVariant returnStatus = wbemObjectDispatch.callMethodA(methodToInvoke);

				// Print out the meaning out return code
				System.out.println(ErrorCodes.SERVICE_ERRORS.get(returnStatus.getObjectAsInt()));
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (dcomSession != null) {
				try {
					JISession.destroySession(dcomSession);
				} catch (Exception ex) {
					ex.printStackTrace();
				}
			}
		}
	}

	/**
	 * Retrieve a session.
	 *
	 * @param domain
	 * @param user
	 * @param pass
	 * @return
	 * @throws Exception
	 */
	private static JISession init(String domain, String user, String pass) throws Exception {
		JISystem.getLogger().setLevel(Level.OFF);
		JISystem.setAutoRegisteration(true);

		JISession dcomSession = JISession.createSession(domain, user, pass);
		dcomSession.useSessionSecurity(true);
		return dcomSession;
	}
}

Download source

The attached source code has 3 programs:

  1. PrintInstances.java prints all instances of a given class. For e.g., to retrieve a list of services use Win32_Service in WML.
  2. SimpleServiceManager.java starts or stops a given service.
  3. ServiceManager.java starts or stops a service by starting/stopping any dependents.

Click to download source code (Eclipse project)

39 Comments

  • Hi Vijey,

    Thank you so much for posting this excellant code example.

    I have derived from your example and wanted to get the system information from the remote server. Here I’m trying to get the information of the available disk drives, but it only list single disk drive.

    How do I loop it through to get all the disk drives available.


    String domain = "mydomain";
    String user = "administrator"
    String password = "password";
    String hostName = "192.168.254.2";

    JISession dcomSession = null;
    try {
    dcomSession = init(domain , user, password);
    JIComServer 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());

    final int RETURN_IMMEDIATE = 0x10;
    final int FORWARD_ONLY = 0x20;
    params = new Object[] {
    new JIString("SELECT * FROM Win32_LogicalDisk"),
    JIVariant.OPTIONAL_PARAM(),
    new JIVariant(new Integer(RETURN_IMMEDIATE + FORWARD_ONLY))
    };
    JIVariant[] servicesSet = wbemServices.callMethodA("ExecQuery", params);
    System.out.println("~~~~~~~~~~~~~~~~~" + servicesSet.length);
    IJIDispatch wbemObjectSet = (IJIDispatch) narrowObject(servicesSet[0].getObjectAsComObject());

    JIVariant newEnumvariant = wbemObjectSet.get("_NewEnum");
    IJIComObject enumComObject = newEnumvariant.getObjectAsComObject();
    IJIEnumVariant enumVariant = (IJIEnumVariant) narrowObject(enumComObject.queryInterface(IJIEnumVariant.IID));

    Object[] elements = enumVariant.next(1);
    System.out.println("~~~~~~~~~~~~~~~~~" + elements.length);
    JIArray aJIArray = (JIArray) elements[0];

    JIVariant[] array = (JIVariant[]) aJIArray.getArrayInstance();
    System.out.println("~~~~~~~~~~~~~~~~~" + array.length);
    for (JIVariant variant : array) {
    IJIDispatch wbemObjectDispatch = (IJIDispatch) narrowObject(variant.getObjectAsComObject());

    // Print object as text. Optional - comment if not needed
    JIVariant[] v = wbemObjectDispatch.callMethodA("GetObjectText_", new Object[] {0});
    for (int i = 0; i < v.length ; i++) {
    System.out.println(v[i].getObjectAsString().getString());
    }

    }
    } catch (Exception e) {
    e.printStackTrace();
    } finally {
    if (dcomSession != null) {
    try {
    JISession.destroySession(dcomSession);
    } catch (Exception ex) {
    ex.printStackTrace();
    }
    }
    }

    Thanks in advance,

    Dushan

  • I found your Java example PrintInstances.java does the same.

    Thanks a lot for the wonderful work.

  • Dushan, Thanks for the kind words.

    As you have found PrintInstances.java iterates over a collection and prints text representation of an object by invoking GetObjectText_. However, if you want more than a String representation, you can invoke appropriate methods of a class and get the exact information you are looking for. You’ll need to know the methods a class exposes and MSDN can help you with that.

    This page http://msdn.microsoft.com/en-us/library/aa394592(VS.85).aspx shows you classes that’ll help obtain information about disk drives etc. In the attached source code, you will see a class called ServiceManager which helps manage services by invoking methods of Win32_Service class. Perhaps by following the ServiceManager class and the examples shown in the link above, you can implement a solution.

  • Hi Vijey,

    Thank you once again for the guidance.

    This really helps me to make my project success.

    Dushan

  • 1st of all.. thx.. that is amazing
    but this code print the information as string.. and i need to get them without doing some process on the string..
    is there a way to return them as a array or object so i can get for example just the PeakVirtualSize or just PeakWorkingSetSize from this object without doing string process (using string method to get some sub string)

    thx

  • Suleiman,

    Yes, I have 2 more examples in the attached zip file which show how to iterate over a collection of objects returned by WQL and invoke methods on them. Also please see my response to Dushan above.

    Regards,
    Vijay

  • following is out put of my program

    instance of Win32_Processor
    {
    Caption = “x86 Family 6 Model 15 Stepping 13″;
    DeviceID = “CPU0″;
    };

    is it possible to get only Caption like
    Caption = “x86 Family 6 Model 15 Stepping 13″;

  • Hi
    When using your program I am getting Access Denied. Do you have a documentation on what all to install and how to install and then run your sample programs attached?
    After I get the feel of the program, I have to extend it to contrail the Hyper-V layer and then control the specific VM’s hosted on it.

    Would some one direct me on this task?

  • Hi,

    How do I get a handle to the individual properties of an object. I need to get the individual name/value pairs of an object. I can call methods but not properties of a WMI object?

    Do you know how to do that?

    Regards
    Hozefa

  • Hi ,
    I am trying J-Interop for first time . I have a requirement to connect to remote server and run netstat command. Can some one give an example.

    PrintInstances gave an exception for remote server , however its working fine for local .

    org.jinterop.dcom.impls.automation.JIAutomationException: Exception occurred. [0x80020009]
    at org.jinterop.dcom.impls.automation.JIDispatchImpl.invoke(JIDispatchImpl.java:333)
    at org.jinterop.dcom.impls.automation.JIDispatchImpl.callMethodA(JIDispatchImpl.java:520)
    at org.jinterop.dcom.impls.automation.JIDispatchImpl.callMethodA(JIDispatchImpl.java:526)
    at org.jinterop.dcom.impls.automation.JIDispatchImpl.callMethodA(JIDispatchImpl.java:477)
    at PrintInstances.main(PrintInstances.java:57)
    Caused by: org.jinterop.dcom.common.JIRuntimeException: Exception occurred. [0x80020009]
    at org.jinterop.dcom.core.JICallBuilder.readResult(JICallBuilder.java:1078)
    at org.jinterop.dcom.core.JICallBuilder.read(JICallBuilder.java:957)
    at ndr.NdrObject.decode(NdrObject.java:19)
    at rpc.ConnectionOrientedEndpoint.call(ConnectionOrientedEndpoint.java:138)
    at rpc.Stub.call(Stub.java:112)
    at org.jinterop.dcom.core.JIComServer.call(JIComServer.java:870)
    at org.jinterop.dcom.core.JIComServer.call(JIComServer.java:825)
    at org.jinterop.dcom.core.JIComObjectImpl.call(JIComObjectImpl.java:266)
    at org.jinterop.dcom.core.JIComObjectImpl.call(JIComObjectImpl.java:153)
    at org.jinterop.dcom.impls.automation.JIDispatchImpl.invoke(JIDispatchImpl.java:315)
    … 4 more

  • Hello jribeauv,

    Thanks for reporting the issue on Server2008 R2. I don’t have access to a Server2008 R2 but when I get a chance I’ll explore the problem.

    In the mean time, your link to the discussion on the issue should help others who run into this problem.

    Thanks again,
    Vijay

  • Hi,

    thanks for the great examples. I managed to connect to a win 2008 r2 server and can get, for example, the Win32_Process listing. Now I want to get information on Msvm_VirtualSwitch and other hyper-v related objects. In your servicemanager example I just changed

    (“SELECT * FROM Win32_Service WHERE Caption = ‘” + serviceName + “‘”),

    to

    (“SELECT * FROM Msvm_VirtualSwitch”),

    but that gives me an error in the following line of code:

    Object[] elements = enumVariant.next(1);

    Error message is:
    org.jinterop.dcom.common.JIException: Message not found for errorCode: 0×80041010
    at org.jinterop.dcom.core.JIComServer.call(JIComServer.java:879)
    at org.jinterop.dcom.core.JIComServer.call(JIComServer.java:825)
    at org.jinterop.dcom.core.JIComObjectImpl.call(JIComObjectImpl.java:266)
    at org.jinterop.dcom.core.JIComObjectImpl.call(JIComObjectImpl.java:153)
    at org.jinterop.dcom.impls.automation.JIEnumVARIANTImpl.next(JIEnumVARIANTImpl.java:55)
    at ServiceManager.manageService(ServiceManager.java:134)
    at ServiceManager.start(ServiceManager.java:57)
    at ServiceManager.main(ServiceManager.java:44)
    Caused by: org.jinterop.dcom.common.JIRuntimeException: Message not found for errorCode: 0×80041010
    at org.jinterop.dcom.core.JICallBuilder.readResult(JICallBuilder.java:1078)
    at org.jinterop.dcom.core.JICallBuilder.read(JICallBuilder.java:957)
    at ndr.NdrObject.decode(NdrObject.java:19)
    at rpc.ConnectionOrientedEndpoint.call(ConnectionOrientedEndpoint.java:138)
    at rpc.Stub.call(Stub.java:112)
    at org.jinterop.dcom.core.JIComServer.call(JIComServer.java:870)
    … 7 more

    Not sure what’s going on … the Hyper-V server is running several virtual machines and should have at least one virtual switch. The hyper-v server is managed through Microsoft Virtual Server Management Software – could that be issue.

    Thanks in advance,
    Kurt

  • Hi ,

    I want to get properties of instances of WMI inner class.Is there any way to get individual property value only instead of getting whole objwct as string?

    Thanks in advance.

    Regards,
    Devayani

  • Hi, Thanks for the wonderful work. How would I start a process. Could you provide an example for the same …

  • I want to Get the CPU%,Memory and Diskdrive Sizes of a remote Windows Machine, I tested the ServieManager.java, It was working Fine,

    Can anyone help me out how to get the Cpu,Memory and DiskDrive info using this

    Thanks in advance

  • Hello i am getting the following error, even though i supplied domain, hostname as localhost, user , password. But the thing is, m not using any password to boot up my machine.
    what are the values should be coming at domain, user, password as i have not created any user or password in my machine.

    org.jinterop.dcom.common.JIException: The attempted logon is invalid. This is either due to a bad username or authentication information. [0xC000006D]
    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.(JIComServer.java:413)
    at com.oo.jintero.SimpleServiceManager.manageService(SimpleServiceManager.java:99)
    at com.oo.jintero.SimpleServiceManager.stop(SimpleServiceManager.java:71)
    at com.oo.jintero.SimpleServiceManager.main(SimpleServiceManager.java:45)
    Caused by: jcifs.smb.SmbAuthException: Logon failure: unknown user name or bad password.
    at jcifs.smb.SmbTransport.checkStatus(SmbTransport.java:510)
    at jcifs.smb.SmbTransport.send(SmbTransport.java:622)
    at jcifs.smb.SmbSession.sessionSetup(SmbSession.java:280)
    at jcifs.smb.SmbSession.send(SmbSession.java:233)
    at jcifs.smb.SmbTree.treeConnect(SmbTree.java:154)
    at jcifs.smb.SmbFile.doConnect(SmbFile.java:847)
    at jcifs.smb.SmbFile.connect(SmbFile.java:890)
    at jcifs.smb.SmbFile.connect0(SmbFile.java:816)
    at jcifs.smb.SmbFileInputStream.(SmbFileInputStream.java:73)
    at jcifs.smb.SmbFileInputStream.(SmbFileInputStream.java:62)
    at jcifs.smb.SmbFile.getInputStream(SmbFile.java:2765)
    at rpc.ncacn_np.RpcTransport.attach(RpcTransport.java:91)
    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)
    … 6 more

  • I am not able to connect my own local machine using the code at very first page…

  • Hi,
    I have a problem getting all disks information.
    I do this:

    params = new Object[] {
    new JIString(“SELECT * FROM Win32_LogicalDisk”),
    JIVariant.OPTIONAL_PARAM(),
    new JIVariant(new Integer(RETURN_IMMEDIATE + FORWARD_ONLY))
    };

    JIVariant[] servicesSet = wbemServices.callMethodA(“ExecQuery”, params);

    later I could do something like this:
    elements = enumVariant.next(1);
    or elements = enumVariant.next(2);
    or elements = enumVariant.next(n); where n is the mumber of disks the machine has, but, how can I get how many disks the machine have to do a proper iteration?

    Thanks

  • Hi Concerned,

    Is it possible to execute script on remote machine from windows machine.

    Please help me regarinding this issue.

    Thanks,
    Anitha Tanda

  • Hi everyone

    I have already developed a java OPC client with the openscada source and the J interop librairies.

    This works well. I can connect my client to any server and write and read any values…

    But I have strange errors when I am performing a lot of readings.
    In fact, I can perfectly read one or many values for 3 to 10 minutes and suddendly, the program returns me different errors as : the server threw an exception or unspecified error.

  • I get following exception when try to run PrintInstances.java, can anybody shed any light please !

    [java][/java] org.jinterop.dcom.impls.automation.JIAutomationException: Exception
    occurred. [0x80020009]
    [java][/java] at org.jinterop.dcom.impls.automation.JIDispatchImpl.invoke(JIDi
    spatchImpl.java:333)
    [java][/java] at org.jinterop.dcom.impls.automation.JIDispatchImpl.callMethodA
    (JIDispatchImpl.java:520)
    [java][/java] at org.jinterop.dcom.impls.automation.JIDispatchImpl.callMethodA
    (JIDispatchImpl.java:526)
    [java][/java] at org.jinterop.dcom.impls.automation.JIDispatchImpl.callMethodA
    (JIDispatchImpl.java:477)
    [java][/java] at PrintInstances.main(Unknown Source)
    [java][/java] Caused by: org.jinterop.dcom.common.JIRuntimeException: Exception oc
    curred. [0x80020009]
    [java][/java] at org.jinterop.dcom.core.JICallBuilder.readResult(JICallBuilder
    .java:1078)
    [java][/java] at org.jinterop.dcom.core.JICallBuilder.read(JICallBuilder.java:
    957)
    [java][/java] at ndr.NdrObject.decode(NdrObject.java:19)
    [java][/java] at rpc.ConnectionOrientedEndpoint.call(ConnectionOrientedEndpoin
    t.java:138)
    [java][/java] at rpc.Stub.call(Stub.java:112)
    [java][/java] at org.jinterop.dcom.core.JIComServer.call(JIComServer.java:870)

    [java][/java] at org.jinterop.dcom.core.JIComServer.call(JIComServer.java:825)

    [java][/java] at org.jinterop.dcom.core.JIComObjectImpl.call(JIComObjectImpl.j
    ava:266)
    [java][/java] at org.jinterop.dcom.core.JIComObjectImpl.call(JIComObjectImpl.j
    ava:153)
    [java][/java] at org.jinterop.dcom.impls.automation.JIDispatchImpl.invoke(JIDi
    spatchImpl.java:315)
    [java][/java] … 4 more

  • Langlois,
    you said that you can connect to any servers, including windows 2008 R2? If so, can you share your solutions?

  • Another question: you said there are two methods to access the WMI. j-interop uses the SWbemScripting.SWbemLocator. I was wondering if you can use the WMI Moniker to access the WMI, that is, through “winmgmts://”. If yes, how it looks like?

  • Thanks for this great example and clear explanation.

  • Hi,
    Execellent article. I have a requirement to develop a java application which will run on windows and linux and it needs to create a service on a remote windows host. How can jop be used for it ? Any information will be helpful.

    Thanks,
    Nitin

  • @ayengin, @Nitin,
    Thanks for the comments.

    @Nitin,
    The attached zip file has an example showing how to connect to a remote Windows server. Also, please see a link above that points to a discussion on sourceforge forums.

    Thanks.

  • Hi Vijey,

    excellent article and ur example works fine. i went through similar code which was published in other blogs/forums, but none worked fine.

    Thanks,
    Nalaka

  • Hi Vijey,

    i have a question regarding executing an exe in a given remote computer in the network.

    i found a way to do it using VBScript. but i am not able to convert that into java using J-Interop. can you please help me with this.

    below is the vbscript code:
    ………………………
    strCommand = “calc.exe”

    Const INTERVAL = “n”
    Const MINUTES = 1

    Set objScheduledJob = objWMIService.Get(“Win32_ScheduledJob”)
    Set objSWbemDateTime = CreateObject(“WbemScripting.SWbemDateTime”)

    objSWbemDateTime.SetVarDate(DateAdd(INTERVAL, MINUTES, Now()))
    errReturn = objScheduledJob.Create(strCommand, objSWbemDateTime.Value, False, 0, 0, True, intJobID)

    ………………………

    i did the following in my java code. but not sure whats the next step.(or even the below is the correct way?)

    /////

    params = new Object[]{
    new JIString(“Win32_ScheduledJob”),
    new Integer(0),
    JIVariant.OPTIONAL_PARAM()
    };
    JIVariant[] servicesSet = wbemServices.callMethodA(“InstancesOf”, params);
    IJIDispatch wbemObjectSet = (IJIDispatch) narrowObject(servicesSet[0].getObjectAsComObject());

    ……?
    /////

    appreciate ur help.

    Thanks,
    Nalaka

  • You example was great,
    but whenever I try to run the example it gives me

    C:\Oracle\Middleware\jdk160_24\bin\javaw.exe -client -classpath “C:\JDeveloper\mywork\WMI\.adf;C:\JDeveloper\mywork\WMI\Client\classes;C:\Documents and Settings\husseinw\My Documents\Downloads\Java\Controls\j-Interop_2_08\j-Interop\lib\j-interop.jar;C:\Documents and Settings\husseinw\My Documents\Downloads\Java\Controls\j-Interop_2_08\j-Interop\lib\j-interopdeps.jar;C:\Documents and Settings\husseinw\My Documents\Downloads\Java\Controls\j-Interop_2_08\j-Interop\lib\jcifs-1.2.19.jar;C:\Documents and Settings\husseinw\My Documents\Downloads\oshi-1.0\bin\jna.jar;C:\Documents and Settings\husseinw\My Documents\Downloads\oshi-1.0\bin\oshi-core.jar;C:\Documents and Settings\husseinw\My Documents\Downloads\oshi-1.0\bin\platform.jar;C:\Documents and Settings\husseinw\My Documents\Downloads\hyperic-sigar-1.6.4\hyperic-sigar-1.6.4\sigar-bin\lib\log4j.jar;C:\Documents and Settings\husseinw\My Documents\Downloads\hyperic-sigar-1.6.4\hyperic-sigar-1.6.4\sigar-bin\lib\sigar.jar” -Djavax.net.ssl.trustStore=C:\DOCUME~1\husseinw\LOCALS~1\Temp\trustStore6299148114482935867.jks PrintInstances
    org.jinterop.dcom.common.JIException: Message not found for errorCode: 0xC000005E
    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.(JIComServer.java:413)
    at PrintInstances.main(PrintInstances.java:44)
    Caused by: jcifs.smb.SmbException: There are currently no logon servers available to service the logon request.
    at jcifs.smb.SmbTransport.checkStatus(SmbTransport.java:522)
    at jcifs.smb.SmbTransport.send(SmbTransport.java:622)
    at jcifs.smb.SmbSession.sessionSetup(SmbSession.java:280)
    at jcifs.smb.SmbSession.send(SmbSession.java:233)
    at jcifs.smb.SmbTree.treeConnect(SmbTree.java:154)
    at jcifs.smb.SmbFile.doConnect(SmbFile.java:847)
    at jcifs.smb.SmbFile.connect(SmbFile.java:890)
    at jcifs.smb.SmbFile.connect0(SmbFile.java:816)
    at jcifs.smb.SmbFileInputStream.(SmbFileInputStream.java:73)
    at jcifs.smb.SmbFileInputStream.(SmbFileInputStream.java:62)
    at jcifs.smb.SmbFile.getInputStream(SmbFile.java:2765)
    at rpc.ncacn_np.RpcTransport.attach(RpcTransport.java:91)
    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
    Process exited with exit code 0.

    would you please help in this.

  • @Nalaka, thanks for the comments. Sorry I couldn’t reply in time.

    @wail Salem, are you using a domain to login (as in DOMAIN\\username)?

  • I copied your code but I have this error
    org.jinterop.dcom.common.JIException: Message not found for errorCode: 0xC0000034
    at org.jinterop.winreg.smb.JIWinRegStub.winreg_OpenHKLM(JIWinRegStub.java:102)
    at org.jinterop.dcom.core.JIProgId.getIdFromWinReg(JIProgId.java:122)
    at org.jinterop.dcom.core.JIProgId.getCorrespondingCLSID(JIProgId.java:154)
    at org.jinterop.dcom.core.JIComServer.(JIComServer.java:395)
    at SimpleServiceManager.manageService(SimpleServiceManager.java:97)
    at SimpleServiceManager.stop(SimpleServiceManager.java:69)
    at SimpleServiceManager.main(SimpleServiceManager.java:43)
    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.(SmbFileOutputStream.java:142)
    at jcifs.smb.TransactNamedPipeOutputStream.(TransactNamedPipeOutputStream.java:32)
    at jcifs.smb.SmbNamedPipe.getNamedPipeOutputStream(SmbNamedPipe.java:187)
    at rpc.ncacn_np.RpcTransport.attach(RpcTransport.java:91)
    at rpc.Stub.attach(Stub.java:105)
    at rpc.Stub.call(Stub.java:109)
    at org.jinterop.winreg.smb.JIWinRegStub.winreg_OpenHKLM(JIWinRegStub.java:100)

  • Nice example,
    I want to install .msi file on remote machine which is connected in networking.
    so how can i accomplished this task using J-Interop?????????
    please help me.

  • I want to take snapshot of virtual machine. I want to do with JInterop. But i dont know how to do. Method available in “CreateVirtualSystemSnapshot Method of the Msvm_VirtualSystemManagementService Class”. Please help me to do.

    Thanks in advance
    Nandakumar

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>