jacob-project icon indicating copy to clipboard operation
jacob-project copied to clipboard

Support WMI

Open EJP286CRSKW opened this issue 1 year ago • 5 comments

WMI is a layer over COM with its own peculiarities. Not easy to use with COM directly. I have developed a thin layer over Jacob that handles WMI, consisting of six small interfaces and classes. I'll post it here after some more testing.

EJP286CRSKW avatar Sep 01 '23 04:09 EJP286CRSKW

Provisional Javadoc attached for comment. Jacob-WMI-Javadoc.zip

EJP286CRSKW avatar Sep 18 '23 01:09 EJP286CRSKW

Do you have any other examples?

If there is another release, I'm going to drop 32 bit process support. Is that a problem?

freemansoft avatar Mar 18 '24 02:03 freemansoft

I have 9 test classes and an entire implementation ready to contribute when I next get a window to work on this. Now consists of 37 interfaces and classes. Example test below.

Please don't remove 32-bit support. At present that is the only one I can build for.

Sample test case, for the common case of enumerating and interrogating Services:

/*
 * Copyright (c) Esmond Pitt, 2023.
 * All rights reserved.
 */
package com.jacob.wmi;

import com.jacob.com.ComThread;
import com.jacob.com.Variant;
import java.util.Date;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.FixMethodOrder;
import org.junit.Rule;
import org.junit.rules.TestName;
import org.junit.runners.MethodSorters;

/**
 *
 * @author Esmond Pitt
 */
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class SWbemServicesTest
{
    @Rule
    public TestName name = new TestName();
    
    public SWbemServicesTest()
    {
    }
    
    @BeforeClass
    public static void setUpClass()
    {
    }
    
    @AfterClass
    public static void tearDownClass()
    {
    }
    
    @Before
    public void setUp()
    {
        System.out.println("SWbemServicesTest."+name.getMethodName());
        ComThread.InitMTA();
    }
    
    @After
    public void tearDown()
    {
        ComThread.Release();
    }
    
    /**
     * Test of constructors of class SWbemServices.
     * This demonstrates that "winmgmts:" connects to "winmgmts:\\\\.\\root\\CIMv2".
     */
    public void testConstructor1()
    {
        SWbemServices   services = new SWbemServices();
        SWbemObject w32p = services.getService("Win32_Process");
//        System.out.println(w32p.getPropertyAsString("CreationClassName"));
//        w32p
//            .getProperties()
//            .stream()
//            .forEach(System.out::println)
//            ;
    }
    
    /**
     * Test of constructors of class SWbemServices.
     */
    public void testConstructor2()
    {
        SWbemServices   services = new SWbemServices("winmgmts:\\\\.\\root\\CIMV2");
        SWbemObject w32p = services.getService("Win32_Process");
        System.out.println(w32p);
    }

    /**
     * Test of associatorsOf() method, of class SWbemServices.
     */
    @Test
    public void testAssociatorsOf()
    {
        SWbemLocator    locator = new SWbemLocator();
        SWbemServices services = locator.connectServer(".", "root\\CIMv2", null, null);
        SWbemObjectSet set = services.associatorsOf
        (
            "Win32_Service.Name='MySQL'",
            null,
            null,
            null,
            null,
            false,
            false,
            null,
            null,
            WbemFlags.ReturnImmediately|WbemFlags.ForwardOnly,
//            WbemFlags.ReturnWhenComplete,
            null
        );
//        SWbemLastError   lastError  = new SWbemLastError();
//        System.out.println(set.getCount()+" instances of Win32_service");
        set
            .stream()
            .forEach(System.out::println)
            ;
    }

    /**
     * Test of associatorsOfAsync() method, of class SWbemServices.
     */
    @Test
    public void testAssociatorsOfAsync()
    {
        SWbemLocator    locator = new SWbemLocator();
        SWbemServices services = locator.connectServer(".", "root\\CIMv2", null, null);
        SWbemSink    sink = new SWbemDebugSink()
        {
            @Override
            protected void onCompleted(int result, SWbemLastError errorObject, SWbemNamedValueSet asyncContext)
            {
                super.onCompleted(result, errorObject, asyncContext);
                synchronized (this)
                {
                    this.notifyAll();
                }
            }
        };
        services.associatorsOfAsync
        (
            sink,
            "Win32_Service.Name='MySQL'",
            null,
            null,
            null,
            null,
            false,
            false,
            null,
            null,
            WbemFlags.SendStatus,
            null,
            null
        );
//        E_CALL_CANCELLED=0x80041032
        try
        {
            synchronized (sink)
            {
                // Wait for the sink to get OnComplete.
                sink.wait(30*1000);
            }
        }
        catch (InterruptedException exc)
        {
            exc.printStackTrace();
        }
        System.out.println(name.getMethodName()+": cancelling sink");
        sink.cancel();
        System.out.println(name.getMethodName()+": cancelled sink");
    }
    
    /**
     * Test of execNotificationQuery method, of class SWbemServices.
     */
    @Test
    public void testExecNotificationQuery()
    {
        SWbemLocator    locator = new SWbemLocator();
        SWbemServices s = locator.connectServer(".", "root\\CIMv2", null, null);
//        s
//            .getMethods()
//            .stream()
//            .forEach(m -> System.out.println(m.name.getMethodName()))
//            ;
        SWbemSink sink = new SWbemDebugSink()
        {
//            @Override
//            protected void onObjectReady(SWbemObject object, SWbemNamedValueSet asyncContext)
//            {
//                super.onObjectReady(object, asyncContext);
//            }

            @Override
            protected void onCompleted(int result, SWbemLastError errorObject, SWbemNamedValueSet asyncContext)
            {
                super.onCompleted(result, errorObject, asyncContext);
                synchronized (this)
                {
                    this.notifyAll();
                }
            }
        }
        ;
        SWbemNamedValueSet   context = new SWbemNamedValueSet();
        context.add("Source", new Variant("testExecNotificationQueryAsync"));
        // Now using a disk activity query so we don't have to start and stop processes.
        SWbemEventSource source = s.execNotificationQuery
        (
//            "SELECT * FROM __InstanceCreationEvent WITHIN 2 WHERE TargetInstance ISA 'Win32_Process'",
            // __InstanceOperationEvent is the base class of __InstanceCreationEvent, __InstanceDeletionEvent, and __InstanceModificationEvent.
//            "SELECT * FROM __InstanceOperationEvent WITHIN 2 WHERE TargetInstance ISA 'Win32_LogicalDisk'",
            "SELECT * FROM __InstanceModificationEvent WITHIN 2 WHERE TargetInstance ISA 'Win32_LogicalDisk'",
            0,
            null
        );
//        System.out.println(new Date()+": waiting for you to start a process");
        // Start notepad in another thread.
//        Thread  t = new Thread
//        (
//                () ->
//                {
//                    try
//                    {
////                        System.out.println("Starting notepad.exe");
//                        Process p = Runtime.getRuntime().exec("c:\\windows\\notepad.exe");
//                        synchronized (sink)
//                        {
//                            // Wait for the sink to get OnComplete.
//                            sink.wait(10*1000);
//                        }
////                        System.out.println("Destroying");
//                        p.destroyForcibly();
////                        System.out.println("Destroyed");
//                    }
//                    catch (IOException|InterruptedException exc)
//                    {
//                        exc.printStackTrace();
//                    }
//                }
//        );
//        t.start();
        System.out.println(new Date()+": calling nextEvent()");
        SWbemObject o =
                // Test the timeout.
                // If there is a timeout here a JVM crash ensues.
                // This is perhaps a Jacob problem,
                // as this is a method which can return null instead of an object,
                // which may be unexplored territory.
//                source.nextEvent(3*1000)
                // Test the iterator, which also tests nextEvent().
                source.iterator().next();
                ;
        System.out.println("nextEvent="+o);
        if (o == null)
        {
            System.out.println(new Date()+": nextEvent() timed out");
        }
        else
        {
            System.out.println(new Date()+": nextEvent() completed");
            o
                .getProperties()
                .stream()
                .forEach(System.out::println)
                ;
        }
        // Cancel the query, otherwise this method will never exit.
        System.out.println(name.getMethodName()+": cancelling WbemEventSource");
        source.cancel();
        System.out.println(name.getMethodName()+": cancelled WbemEventSource");
//        try
//        {
//            t.join();
//        }
//        catch (InterruptedException exc)
//        {
//            exc.printStackTrace();
//        }
    }
    
    @Test
    public void testNewVariantIsNull()
    {
        Variant v = new Variant();
        System.out.println(v.isNull());
    }

    /**
     * Test of testExecNotificationQueryAsync method, of class SWbemServices.
     */
    @Test
    public void testExecNotificationQueryAsync()
    {
//        if (true)
//            // Not working. JMV doesn't exit.
//            return;
        SWbemLocator    locator = new SWbemLocator();
        SWbemServices services = locator.connectServer(".", "root\\CIMv2", null, null);
        SWbemSink sink = new SWbemDebugSink()
        {
//            @Override
//            protected void onObjectReady(SWbemObject object, SWbemNamedValueSet asyncContext)
//            {
//                super.onObjectReady(object, asyncContext);
//            }

            @Override
            protected void onCompleted(int result, SWbemLastError errorObject, SWbemNamedValueSet asyncContext)
            {
//                System.out.println("onCompleted called: result=0x"+Integer.toHexString(result));
                super.onCompleted(result, errorObject, asyncContext);
                synchronized (this)
                {
                    this.notifyAll();
                }
            }
        }
        ;
        SWbemNamedValueSet   context = new SWbemNamedValueSet();
        context.add("Source", new Variant("testExecNotificationQueryAsync"));
        // Now using a disk activity query so we don't have to start and stop processes.
        services.execNotificationQueryAsync
        (
            sink,
//            "SELECT * FROM __InstanceCreationEvent WITHIN 2 WHERE TargetInstance ISA 'Win32_Process'",
            // __InstanceOperationEvent is the base class of __InstanceCreationEvent, __InstanceDeletionEvent, and __InstanceModificationEvent.
//            "SELECT * FROM __InstanceOperationEvent WITHIN 2 WHERE TargetInstance ISA 'Win32_LogicalDisk'",
            "SELECT * FROM __InstanceModificationEvent WITHIN 2 WHERE TargetInstance ISA 'Win32_LogicalDisk'",
            // WbemFlags.QueryPrototype| // DOES NOT WORK
            WbemFlags.SendStatus,
            null,
            context
        );
        try
        {
//            System.out.println(new Date()+": waiting for you to start a process");
            // TODO Start notepad in another thread.
//            Thread  t = new Thread
//            (
//                () ->
//                {
//                    try
//                    {
////                        System.out.println("Starting notepad.exe");
//                        Process p = Runtime.getRuntime().exec("c:\\windows\\notepad.exe");
//                        synchronized (sink)
//                        {
//                            // Wait for the sink to get OnComplete.
//                            sink.wait(10*1000);
//                        }
////                        System.out.println("Destroying");
//                        p.destroyForcibly();
////                        System.out.println("Destroyed");
//                    }
//                    catch (IOException|InterruptedException exc)
//                    {
//                        exc.printStackTrace();
//                    }
//                }
//            );
//            t.start();
            synchronized (sink)
            {
                // Wait for the sink to get OnComplete.
                sink.wait(10*1000);
            }
            System.out.println(new Date()+": wait completed or timed out");
//            t.join();
        }
        catch (InterruptedException exc)
        {
            exc.printStackTrace();
            System.out.println(new Date()+": wait interrupted");
        }
        finally
        {
            // This test never exits.
            // WELL IT SHOULD, and cancelling the sink is how.
            System.out.println(name.getMethodName()+": cancelling the async query");
            // Works occasionally.
            // Sometimes JVM exits abnomrmally.
            // Mostly the JVM doesn't exit at all after running this test.
            sink.cancel();
            System.out.println(name.getMethodName()+": cancelled the async query");
            services.safeRelease(); // Didn't help.
            System.out.println("Released the SWbemServices object");
        }
    }

    /**
     * Test of execQuery method, of class SWbemServices.
     */
    @Test
    public void testExecQuery()
    {
        SWbemLocator    locator = new SWbemLocator();
        SWbemServices s = locator.connectServer(".", "root\\CIMv2", null, null);
        
//        Events  e = new Events();
//        DispatchEvents  ev = new DispatchEvents(s, e);
        
        // Execute a query to retrieve all the java.exe processes.
        SWbemObjectSet r = s.execQuery("Select * from Win32_Process where name=\"java.exe\"");
        r
            .stream()
            .map(ax -> ax.getPropertyAsString("Name"))
            .forEach(System.out::println)
            ;
        
        // Get the Win32_Process object.
        SWbemObject w32p = s.getService("Win32_Process");
        
        // Get the 'SetPriority()' method.
        SWbemMethod   m = w32p.getMethod("SetPriority");
        
        // Get an InParameters instance.
        SWbemObject   p = m.getInParameters();
        
        // Set the Priority property to 32 (normal priority).
        p.setProperty("Priority", 32);
        
        // Call the method on all the query results, i.e. set all their priorities to 32.
        System.out.println("SetPriority------:");
        r
            .stream()
            .map(o -> o.execMethod("SetPriority", p))
            .map(o -> o.getPropertyAsInt("ReturnValue"))
            .forEach(System.out::println)
            ;
        
        // Get the owner: demonstration of getting output parameters.
        System.out.println("GetOwner------:");
        r
            .stream()
            .map(o -> o.execMethod("GetOwner", o.getMethod("GetOwner").getInParameters()))
            .forEach
            (
                o ->
                {
                    System.out.println("User="+o.getPropertyAsString("User"));
                    System.out.println("Domain="+o.getPropertyAsString("Domain"));
                    System.out.println("ReturnValue="+o.getPropertyAsInt("ReturnValue"));
                }
            );
    }
    
    @Test
    public void testExecQueryAsync()
    {
        SWbemLocator    locator = new SWbemLocator();
        SWbemServices services = locator.connectServer(".", "root\\CIMv2", null, null);
        SWbemSink    sink = new SWbemDebugSink()
        {
            // onCompleted
            @Override
            protected void onCompleted(int result, SWbemLastError errorObject, SWbemNamedValueSet asyncContext)
            {
                // TODO call the OnCompletionListeners.
    //            System.out.println("onCompleted called");
                super.onCompleted(result, errorObject, asyncContext);
                // Just to confirm the property names, undocumented by Microsoft.
    //            if (result != 0)
    //            {
    //                errorObject
    //                    .getProperties()
    //                    .stream()
    //                    .map(SWbemProperty::getName)
    //                    .forEach(System.out::println)
    //                    ;
    //            }
                if (result != 0)
                    System.out.println(errorObject);
                synchronized (this)
                {
                    this.notifyAll();
                }
            }
            // onObjectPut
            @Override
            protected void    onObjectPut(SWbemObjectPath path, SWbemNamedValueSet asyncContext)
            {
                // TODO call the OnObjectPutListeners.
                System.out.println("OnObjectPut called");
            }
            // onObjectReady
            protected void onObjectReady(SWbemObject object, SWbemNamedValueSet asyncContext)
            {
                // TODO call the OnObjectReadyListeners.
    //            System.out.println("onObjectReady called");
                System.out.println("Name="+object.getPropertyAsString("Name"));
                System.out.println("ConnectionsEstablished="+object.getProperty("ConnectionsEstablished"));
                super.onObjectReady(object, asyncContext);
    //        System.out.println("source="+asyncContext.getPropertyAsString("Source"));
            }
            // onProgress
            protected void onProgress(int upperBound, int current, String message, SWbemNamedValueSet asyncContext)
            {
                // TODO call the OnProgressListeners.
                System.out.println("OnProgress called");
            }
        }
        ;
        SWbemNamedValueSet   nvs = null;
        SWbemNamedValueSet   context = new SWbemNamedValueSet();
        context.add("Source", new Variant("testExecuteQueryAsync"));
//        context
//            .stream()
//            .forEach(nv -> System.out.println("Name="+nv.name.getMethodName()+" Value="+nv.getValue()))
//            ;
        
        // Execute a query to retrieve all the java.exe processes.
        services.execQueryAsync
        (
            sink,
            "Select * from Win32_PerfFormattedData_TCPIP_TCPv4",
            WbemFlags.SendStatus,
            nvs,
            context
        );
//        Events  e = new Events();
//        DispatchEvents  ev = new DispatchEvents(s, e);
        try
        {
            synchronized (sink)
            {
                // Wait for the sink to get OnComplete.
                sink.wait(10*1000);
            }
        }
        catch (InterruptedException exc)
        {
            exc.printStackTrace();
        }
        context
            .stream()
            .forEach(nv -> System.out.println("Name="+nv.getName()+" Value="+nv.getValue()))
            ;
        System.out.println(name.getMethodName()+": cancelling sink");
        sink.cancel();
        System.out.println(name.getMethodName()+": cancelled sink");
        services.safeRelease();
        System.out.println(name.getMethodName()+": releaseed the SWbemServices object");
    }
    
//    public class Events
//    {
//        public void DoneExecuteQuery(Variant[] args)
//        {
//            System.out.println("ExecuteQuery was called with "+args.length+" arguments");
//        }
//        public void DoneGetService(Variant[] args)
//        {
//            System.out.println("GetService was called with "+args.length+" arguments");
//        }
//        // onCompleted
//        public void OnCompletion(long handle, SWbemLastError errorObject, SWbemNamedValueSet asyncContext)
//        {
//            // TODO call the OnCompletionListeners.
//            System.out.println("OnCompletion called");
//        }
//        // onObjectPut
//        public void    onObjectPut(SWbemObjectPath path, SWbemNamedValueSet asyncContext)
//        {
//            // TODO call the OnObjectPutListeners.
//            System.out.println("onObjectPut called");
//        }
//        // onObjectReady
//        public void onObjectReady(SWbemObject object, SWbemNamedValueSet asyncContext)
//        {
//            // TODO call the OnObjectReadyListeners.
//            System.out.println("onObjectReady called");
//        }
//        // onProgress
//        public void onProgress(int upperBound, int current, String message, SWbemNamedValueSet asyncContext)
//        {
//            // TODO call the OnProgressListeners.
//            System.out.println("onProgress called");
//        }
//    }

    /**
     * Test of get() method, of class SWbemServices.
     */
    @Test
    public void testGet()
    {
        SWbemLocator    locator = new SWbemLocator();
        SWbemServices s = locator.connectServer(".", "root\\CIMv2", null, null);
        SWbemObject  o = s.get("Win32_Service.Name='MySQL'", 0, null);
        o
            .getProperties()
            .stream()
            .forEach(System.out::println)
            ;
    }

    /**
     * Test of getAsync() method, of class SWbemServices.
     */
    @Test
    public void testGetAsync()
    {
        SWbemLocator    locator = new SWbemLocator();
        SWbemServices s = locator.connectServer(".", "root\\CIMv2", null, null);
        SWbemSink    sink = new SWbemDebugSink()
        {
            @Override
            protected void onCompleted(int result, SWbemLastError errorObject, SWbemNamedValueSet asyncContext)
            {
                super.onCompleted(result, errorObject, asyncContext);
                synchronized (this)
                {
                    this.notifyAll();
                }
            }

            @Override
            protected void onObjectReady(SWbemObject object, SWbemNamedValueSet asyncContext)
            {
//                super.onObjectReady(object, asyncContext);
                System.out.println("onObjectReady(): got object name="+object.getPropertyAsString("Name"));
            }

        };
        s.getAsync
        (
            sink,
            "Win32_Service.Name='MySQL'",
            WbemFlags.SendStatus,
            null,
            null
        );
        try
        {
            synchronized (sink)
            {
                // Wait for the sink to get OnComplete.
                sink.wait(10*1000);
            }
        }
        catch (InterruptedException exc)
        {
            exc.printStackTrace();
        }
        System.out.println(name.getMethodName()+": cancelling sink");
        sink.cancel();
        System.out.println(name.getMethodName()+": cancelled sink");
    }
    
    /**
     * Test of testGetSecurity method, of class SWbemServices.
     */
    @Test
    public void testGetSecurity()
    {
        SWbemLocator    locator = new SWbemLocator();
        SWbemServices s =
                locator.connectServer(".", "root\\CIMv2", null, null)
//                new SWbemServices()
                ;
        SWbemSecurity    security = s.getSecurity();
        System.out.println("security="+security);
    }
    /**
     * Test of getService method, of class SWbemServices.
     */
    @Test
    public void testGetService()
    {
        SWbemLocator    locator = new SWbemLocator();
        SWbemServices s = locator.connectServer(".", "root\\CIMv2", null, null);
        
        // Get the Win32_Process object.
        SWbemObject w32p = s.getService("Win32_Process");
        
        // List the property names of an instance (a process).
        System.out.println("Properties------:");
        w32p
            .getProperties()
            .stream()
            .map(SWbemProperty::getName)
            .forEach(System.out::println)
            ;
        
        // List the Win32_Process method names.
        System.out.println("Methods------:");
        w32p
            .getMethods()
            .stream()
            .map(SWbemMethod::getName)
            .forEach(System.out::println)
            ;
    }

    /**
     * Test of instancesOf() method, of class SWbemServices.
     */
    @Test
    public void testInstancesOf()
    {
        SWbemLocator    locator = new SWbemLocator();
        SWbemServices services = locator.connectServer(".", "root\\CIMv2", null, null);
        SWbemObjectSet set = services.instancesOf
        (
            "Win32_Service",
            WbemFlags.ReturnImmediately|WbemFlags.ForwardOnly,
//            WbemFlags.ReturnWhenComplete,
            null
        );
        set
            .stream()
            .forEach(o -> System.out.println("Service name="+o.getPropertyAsString("Name")))                
            ;
        System.out.println(set.getCount()+" instances of Win32_service");
    }

    /**
     * Test of instancesOfAsync() method, of class SWbemServices.
     */
    @Test
    public void testInstancesOfAsync()
    {
        SWbemLocator    locator = new SWbemLocator();
        SWbemServices services = locator.connectServer(".", "root\\CIMv2", null, null);
        SWbemSink    sink = new SWbemDebugSink()
        {
            @Override
            protected void onObjectReady(SWbemObject object, SWbemNamedValueSet asyncContext)
            {
//                super.onObjectReady(object, asyncContext);
                System.out.println("Context source="+asyncContext.item("Source"));
                System.out.println("Service name="+object.getPropertyAsString("Name"));
            }

            @Override
            protected void onCompleted(int result, SWbemLastError errorObject, SWbemNamedValueSet asyncContext)
            {
                super.onCompleted(result, errorObject, asyncContext);
                synchronized (this)
                {
                    this.notifyAll();
                }
            }
        };
        SWbemNamedValueSet   context = new SWbemNamedValueSet();
        context.add("Source", new Variant("testInstancesOfAsync"));
        services.instancesOfAsync
        (
            sink,
            "Win32_Service",
            WbemFlags.SendStatus,
            null,
            context
        );
        try
        {
            synchronized (sink)
            {
                // Wait for the sink to get OnComplete.
                sink.wait(10*1000);
            }
        }
        catch (InterruptedException exc)
        {
            exc.printStackTrace();
        }
        System.out.println(name.getMethodName()+": cancelling sink");
        sink.cancel();
        System.out.println(name.getMethodName()+": cancelled sink");
    }

    /**
     * Test of referenceTo() method, of class SWbemServices.
     */
    @Test
    public void testReferencesTo()
    {
        SWbemLocator    locator = new SWbemLocator();
        SWbemServices services = locator.connectServer(".", "root\\CIMv2", null, null);
        /*
            String objectPath,
            String resultClass,
            String role,
            boolean classesOnly,
            boolean schemaOnly,
            String requiredQualifier,
            int flags,
            SWbemNamedValueSet nvs
        */
        SWbemObjectSet set = services.referencesTo
        (
            "Win32_Service",
            null,
            null,
            false,
            false,
            null,
            WbemFlags.ReturnImmediately|WbemFlags.ForwardOnly,
//            WbemFlags.ReturnWhenComplete,
            null
        );
        set
            .stream()
            .forEach(o -> System.out.println("Reference name="+o.getPropertyAsString("Name")))
            ;
        // Can't use getCount() with ForwardOnly.
//        System.out.println(set.getCount()+" references to Win32_service");
    }

    /**
     * Test of referencesToAsync() method, of class SWbemServices.
     */
    @Test
    public void testReferencesToAsync()
    {
        SWbemLocator    locator = new SWbemLocator();
        SWbemServices services = locator.connectServer(".", "root\\CIMv2", null, null);
        SWbemSink    sink = new SWbemDebugSink()
        {
            @Override
            protected void onObjectReady(SWbemObject object, SWbemNamedValueSet asyncContext)
            {
//                super.onObjectReady(object, asyncContext);
                System.out.println("Context source="+asyncContext.item("Source"));
                System.out.println("Reference name="+object.getPropertyAsString("Name"));
            }

            @Override
            protected void onCompleted(int result, SWbemLastError errorObject, SWbemNamedValueSet asyncContext)
            {
                super.onCompleted(result, errorObject, asyncContext);
                synchronized (this)
                {
                    this.notifyAll();
                }
            }
        };
        SWbemNamedValueSet   context = new SWbemNamedValueSet();
        context.add("Source", new Variant("testReferencesToAsync"));
        services.referencesToAsync
        (
            sink,
            "Win32_Service",
            null,
            null,
            false,
            false,
            null,
            WbemFlags.SendStatus,
            null,
            context
        );
        try
        {
            synchronized (sink)
            {
                // Wait for the sink to get OnComplete.
                sink.wait(10*1000);
            }
        }
        catch (InterruptedException exc)
        {
            exc.printStackTrace();
        }
        System.out.println(name.getMethodName()+": cancelling sink");
        sink.cancel();
        System.out.println(name.getMethodName()+": cancelled sink");
    }

    /**
     * Test of subClassesOf() method, of class SWbemServices.
     */
    @Test
    public void testSubClassesOf()
    {
        SWbemLocator    locator = new SWbemLocator();
        SWbemServices services = locator.connectServer(".", "root\\CIMv2", null, null);
        SWbemObjectSet set = services.subClassesOf
        (
            "Win32_Service",
            WbemFlags.ReturnImmediately|WbemFlags.ForwardOnly|WbemQueryFlags.Shallow,
//            WbemFlags.ReturnWhenComplete|WbemQueryFlags.Shallow,
            null
        );
        set
            .stream()
            .peek(System.out::println)
            .forEach(o -> System.out.println("Subclass name="+o.getPropertyAsString("Name")))
            ;
        System.out.println(set.getCount()+" subclass of Win32_service");
    }

    /**
     * Test of subClassesOfAsync() method, of class SWbemServices.
     */
    @Test
    public void testSubClassesOfAsync()
    {
        SWbemLocator    locator = new SWbemLocator();
        SWbemServices services = locator.connectServer(".", "root\\CIMv2", null, null);
        SWbemSink    sink = new SWbemDebugSink()
        {
            @Override
            protected void onObjectReady(SWbemObject object, SWbemNamedValueSet asyncContext)
            {
//                super.onObjectReady(object, asyncContext);
                System.out.println("Context source="+asyncContext.item("Source"));
                System.out.println("Subclass name="+object.getPropertyAsString("Name"));
            }

            @Override
            protected void onCompleted(int result, SWbemLastError errorObject, SWbemNamedValueSet asyncContext)
            {
                super.onCompleted(result, errorObject, asyncContext);
                synchronized (this)
                {
                    this.notifyAll();
                }
            }
        };
        SWbemNamedValueSet   context = new SWbemNamedValueSet();
        context.add("Source", new Variant("testSubClassesOfAsync"));
        services.subClassesOfAsync
        (
            sink,
            "Win32_Service",
            WbemFlags.SendStatus|WbemQueryFlags.Shallow,
            null,
            context
        );
        try
        {
            synchronized (sink)
            {
                // Wait for the sink to get OnComplete.
                sink.wait(10*1000);
            }
        }
        catch (InterruptedException exc)
        {
            exc.printStackTrace();
        }
        System.out.println(name.getMethodName()+": cancelling sink");
        sink.cancel();
        System.out.println(name.getMethodName()+": cancelled sink");
    }
    
}

EJP286CRSKW avatar Mar 18 '24 03:03 EJP286CRSKW

Please don't remove 32-bit support. At present that is the only one I can build for. In any case I will bet money that most of your current users are 32-bit and not up to Java 17. Don't break backwards compatibility please.

EJP286CRSKW avatar Mar 19 '24 00:03 EJP286CRSKW

Rolled back yesterday's commit that removed X86 support. Returned to Java 8

freemansoft avatar Mar 19 '24 01:03 freemansoft