View Javadoc
1   /*
2    * Copyright 2020-2023 The OSHI Project Contributors
3    * SPDX-License-Identifier: MIT
4    */
5   package oshi.demo;
6   
7   import java.util.Objects;
8   
9   import com.sun.jna.platform.win32.COM.COMException;
10  
11  import oshi.annotation.SuppressForbidden;
12  import oshi.driver.windows.wmi.Win32OperatingSystem;
13  import oshi.util.platform.windows.WmiQueryHandler;
14  
15  /**
16   * Class demonstrating WMI stat performance improvements if the user does COM initialization so OSHI doesn't have to
17   */
18  public class UserComInit {
19  
20      private static final int REPETITIONS = 300;
21  
22      @SuppressForbidden(reason = "Using System.out in a demo class")
23      public static void main(String[] args) {
24          wakeUpCom();
25          System.out.println("Collecting statistics with default COM setup");
26          loopWmiQueries();
27          System.out.println("Collecting statistics with user-init COM setup");
28          loopWmiQueriesWithUserCom();
29      }
30  
31      private static void wakeUpCom() {
32          // The first COM query can take extra long so just do one separately
33          Win32OperatingSystem.queryOsVersion();
34      }
35  
36      @SuppressForbidden(reason = "Using System.out in a demo class")
37      private static void loopWmiQueries() {
38          long t = System.nanoTime();
39          for (int i = 0; i < REPETITIONS; i++) {
40              Win32OperatingSystem.queryOsVersion();
41          }
42          t = System.nanoTime() - t;
43          System.out.println("Average ms per rep: " + t / (1_000_000d * REPETITIONS));
44      }
45  
46      private static void loopWmiQueriesWithUserCom() {
47          // Create instance using existing WmiQueryHandler class for convenience, only to
48          // be used for COM init/uninit. Not needed if user initializes COM.
49          WmiQueryHandler handlerForSingleCOMinit = Objects.requireNonNull(WmiQueryHandler.createInstance());
50  
51          boolean singleComInit = false;
52          try {
53              // Initialize using the default query handler. This is unnecessary in a user
54              // application if the application controls COM initialization elsewhere.
55              singleComInit = handlerForSingleCOMinit.initCOM();
56  
57              // Change query handler class to not initialize COM
58              WmiQueryHandler.setInstanceClass(WmiNoComInitQueryHandler.class);
59  
60              loopWmiQueries();
61          } catch (COMException e) {
62              // Ignore for demo. Production code should handle this!
63          } finally {
64              // User should ununitialize COM in their own application
65              if (singleComInit) {
66                  handlerForSingleCOMinit.unInitCOM();
67              }
68          }
69      }
70  }