Get all Snapshots for a Machine (VirtualBox Java API) - java
I'm using the Java API for VirtualBox from the SDK version "VirtualBoxSDK-5.1.22-115126" (vboxjws.jar).
I want to get a List of all snapshots belonging to the IMachine object (object representing one virtual machine) that I'm working with.
IMachine has the method findSnapshot(String nameOrId) which returns a snapshot for the given name or UUID. But I want a list of ALL snapshots the machine has...
The command line interface vboxmanage is able to return a list of all snapshots with the command:
vboxmanage snapshot <uuid|vmname> list
(source: https://www.virtualbox.org/manual/ch08.html#idm4900)
So is this method missing in the API by design or have the developers from Oracle just forgotten to implement it? (would proof that they are just human beings too ;))
Snapshots is a tree structure with a root snapshot, from which all other snapshots originate. You could say it is by design the API call does not exists, but you can implement it yourself directly by going through the tree.
This sample will do just that:
import org.virtualbox_5_1.IMachine;
import org.virtualbox_5_1.ISnapshot;
import org.virtualbox_5_1.IVirtualBox;
import org.virtualbox_5_1.VirtualBoxManager;
public class SnapshotList {
private static void printChilds(ISnapshot snapshot) {
System.out.println("\"" + snapshot.getName() + "\" {" + snapshot.getId() + "}");
for (ISnapshot snapChild : snapshot.getChildren()) {
printChilds(snapChild);
}
}
public static void main(String[] args) {
/*
* WebServices info
*/
String wsHost = "http://localhost:18083";
String wsUser = "user";
String wsPass = "password";
if (args.length < 1 || args[0] == null || args[0].length() < 1) {
System.err.println("Specify the VM name/UUID as first parameter");
System.exit(1);
}
String vmName = args[0];
VirtualBoxManager vboxManager = VirtualBoxManager.createInstance(null);
vboxManager.connect(wsHost, wsUser, wsPass);
try {
IVirtualBox vbox = vboxManager.getVBox();
IMachine vm = vbox.findMachine(vmName);
if (vm.getSnapshotCount() < 1) {
System.out.println("The machine + " + vmName + " has no snapshot");
System.exit(0);
}
// The magic is here: null will give you the root snapshot
printChilds(vm.findSnapshot(null));
} finally {
vboxManager.disconnect();
vboxManager.cleanup();
}
}
}
I assume you know how to configure the WS login & password variables or disable authentication on the WebService process.
The doc of IMachine::findSnapshot() explains that null can be used to fetch the root snapshot, from which you can just process the childs:
Returns a snapshot of this machine with the given UUID. A null
argument can be used to obtain the first snapshot taken on this
machine. To traverse the whole tree of snapshots starting from the
root, inspect the root snapshot's ISnapshot::children attribute and
recurse over those children.
Related
Strange behaviour with indexOf method
We have deployed our Java EE web application in jboss 4.0.2 (we are using JDK 1.6.0_18). In our code we are iterating through the Collection and doing string concatenation of userids in collection (refer below code). On production server, it behaves inconsistently. The userid (2044157) is not found in final string (refer ServerLog line3). If we restart the production jboss server, then it works perfectly fine and it prints all users correctly in final string log. But the problem again reappears after heavy usage (after 5-6 hours). We are not able to replicate the issue on our QA environment. When problem happens, Looks like the indexOf method incorrectly returns that 2044157 is there in strUsers string (even though 2044157 is not there) and hence it goes into else part and printed it in else part log(refer ServerLog line2 - highlighted in bold font). What could be reason for such inconsistent behavior? Code: public class UsersEJB implements SessionBean{ private void processSelectionData{ StringBuilder strUsers = new StringBuilder(""); Collection userVoCollection = dc.retProjectOrgUsers(projectID, strDistributionCompID, porjectDataSource); // This is returning List of 626 UserVO if(log.isDebugEnabled()) log.debug("UserList Size="+userVoCollection.size()+",B4 strUsers="+strUsers.toString()); Iterator it = userVoCollection.iterator(); while(it.hasNext()) { UserVO uVO = (UserVO)it.next(); if(!(strUsers.toString().indexOf("," + uVO.userID.toString() + ",") > -1)) { strUsers.append(uVO.userID.toString()).append(","); loopCntPos++; } else { loopCntNeg++; if(log.isDebugEnabled()) log.debug("UserId="+uVO.userID.toString()+",strUsers="+loopCnt+"="+strUsers.toString()); } loopCnt++; } if(log.isDebugEnabled()) log.debug("COMPANIES_ID1 strUsers="+strUsers.toString() + ",### loopCnt="+loopCnt + ",loopCntPos="+loopCntPos + ",loopCntNeg="+loopCntNeg); } } ServerLog UserList Size=626,B4 strUsers=,1732286,2066065,2096854,1952590,1731333,1732065,1734828,1852547,1732020,1733653,1731278,2079012,1733299,1765873,1733431,1960010,1828681,2047672,1731752,1733172,1784314,1989311,1734795,1732658,1731415,1785285,1785185,1738446,1733139,1732526,1733549,1731078,1804055,1732939,1663167,1732768,1732029,1732504,1989185,1882746,1785428,1731213,1732931,1731296,1733503,1753435,1731667,1936166,1747699,2099764,1482144,1747707,1732953,1771653,1731251,1989303,1755297,1731160,1901283,1782751,1733543,1882693,1733354,1974270,2044300,1732082,1907188,1731872,1955156,1732153,1733260,1731096,1604035,1731914,1731169,1732418,1731240,1989180,1731306,1733533,1882684,1821306,1731178,1731389,1733309,1733104,2078768,1989277,1732542,1733513,1733082,1732630,1733289,1733361,2077522,1733252,1732493,1978847,1733071, UserId=2044157,strUsers=440=,1732286,2066065,2096854,1952590,1731333,1732065,1734828,1852547,1732020,1733653,1731278,2079012,1733299,1765873,1733431,1960010,1828681,2047672,1731752,1733172,1784314,1989311,1734795,1732658,1731415,1785285,1785185,1738446,1733139,1732526,1733549,1731078,1804055,1732939,1663167,1732768,1732029,1732504,1989185,1882746,1785428,1731213,1732931,1731296,1733503,1753435,1731667,1936166,1747699,2099764,1482144,1747707,1732953,1771653,1731251,1989303,1755297,1731160,1901283,1782751,1733543,1882693,1733354,1974270,2044300,1732082,1907188,1731872,1955156,1732153,1733260,1731096,1604035,1731914,1731169,1732418,1731240,1989180,1731306,1733533,1882684,1821306,1731178,1731389,1733309,1733104,2078768,1989277,1732542,1733513,1733082,1732630,1733289,1733361,2077522,1733252,1732493,1978847,1733071,1893797,2137701,2025815,1522850,2027582,1732833,1984513,2037965,1900381,1731514,2044357,2042751,1785407,2118267,2050509,2062445,1934909,1912411,1733673,1731956,1694916,1731951,2048024,1735552,2115155,1732777,2120796,2048007,1845970,1738356,1841988,2101099,2027667,2067876,1734628,1731739,1731893,2051612,1819645,1803654,2037906,1732047,1478544,2073677,2012435,2067977,2073669,1981390,1731124,15916,6766,1978916,1732750,1936298,1891936,1747650,1949484,2101161,1928883,1948164,2013726,1750718,1732164,1733700,1639298,1734968,1732007,1734723,1949403,2137692,1990151,1734617,2101130,1928888,2044163,1732042,1819543,2137672,1735463,1732716,1950975,2025826,1984507,2017645,1372949,1928719,1732684,1952358,1581015,2026878,1731622,1734036,2000528,1734611,2052691,1961286,2107121,1733335,1868846,2000469,1734771,1841953,2118224,2038924,1731609,1735396,2026033,1805573,2107214,1638397,1731502,1731581,2115171,2120903,1892076,2060862,2017603,2002514,1731351,1901274,1760679,1821298,1884485,1777244,1731204,1934917,2000497,1737101,2115043,2121909,2097818,1506144,1953947,1753401,1594875,2135263,1900276,1907168,1851867,1940057,1897000,1765857,2037953,1907085,2037911,2062548,1650062,1801180,1953696,2119602,1605403,1804076,1669286,1844334,1542596,2048001,1938656,1757959,1529666,2070447,1565121,1907065,1944060,2097808,2077490,1843170,1957289,1690800,1823148,1788987,1912477,1738344,1845866,2047996,1962156,1483244,2071932,2127277,1912419,1756748,1999518,1908161,1722312,1548164,1584044,2047896,1856844,1762432,2073439,1861949,1530755,1989292,1852455,2027658,1738380,2067996,1981507,1998543,1958859,1620837,1852555,2012357,1895444,2050380,1789210,1932156,1898948,2046841,2098171,1625335,2138533,2046655,1785464,2105080,2024935,1852446,2073682,1478644,2103660,1751154,1863254,1478332,1849259,1593399,1895334,2075182,2134365,2136657, COMPANIES_ID1 strUsers=,1732286,2066065,2096854,1952590,1731333,1732065,1734828,1852547,1732020,1733653,1731278,2079012,1733299,1765873,1733431,1960010,1828681,2047672,1731752,1733172,1784314,1989311,1734795,1732658,1731415,1785285,1785185,1738446,1733139,1732526,1733549,1731078,1804055,1732939,1663167,1732768,1732029,1732504,1989185,1882746,1785428,1731213,1732931,1731296,1733503,1753435,1731667,1936166,1747699,2099764,1482144,1747707,1732953,1771653,1731251,1989303,1755297,1731160,1901283,1782751,1733543,1882693,1733354,1974270,2044300,1732082,1907188,1731872,1955156,1732153,1733260,1731096,1604035,1731914,1731169,1732418,1731240,1989180,1731306,1733533,1882684,1821306,1731178,1731389,1733309,1733104,2078768,1989277,1732542,1733513,1733082,1732630,1733289,1733361,2077522,1733252,1732493,1978847,1733071,1893797,2137701,2025815,1522850,2027582,1732833,1984513,2037965,1900381,1731514,2044357,2042751,1785407,2118267,2050509,2062445,1934909,1912411,1733673,1731956,1694916,1731951,2048024,1735552,2115155,1732777,2120796,2048007,1845970,1738356,1841988,2101099,2027667,2067876,1734628,1731739,1731893,2051612,1819645,1803654,2037906,1732047,1478544,2073677,2012435,2067977,2073669,1981390,1731124,15916,6766,1978916,1732750,1936298,1891936,1747650,1949484,2101161,1928883,1948164,2013726,1750718,1732164,1733700,1639298,1734968,1732007,1734723,1949403,2137692,1990151,1734617,2101130,1928888,2044163,1732042,1819543,2137672,1735463,1732716,1950975,2025826,1984507,2017645,1372949,1928719,1732684,1952358,1581015,2026878,1731622,1734036,2000528,1734611,2052691,1961286,2107121,1733335,1868846,2000469,1734771,1841953,2118224,2038924,1731609,1735396,2026033,1805573,2107214,1638397,1731502,1731581,2115171,2120903,1892076,2060862,2017603,2002514,1731351,1901274,1760679,1821298,1884485,1777244,1731204,1934917,2000497,1737101,2115043,2121909,2097818,1506144,1953947,1753401,1594875,2135263,1900276,1907168,1851867,1940057,1897000,1765857,2037953,1907085,2037911,2062548,1650062,1801180,1953696,2119602,1605403,1804076,1669286,1844334,1542596,2048001,1938656,1757959,1529666,2070447,1565121,1907065,1944060,2097808,2077490,1843170,1957289,1690800,1823148,1788987,1912477,1738344,1845866,2047996,1962156,1483244,2071932,2127277,1912419,1756748,1999518,1908161,1722312,1548164,1584044,2047896,1856844,1762432,2073439,1861949,1530755,1989292,1852455,2027658,1738380,2067996,1981507,1998543,1958859,1620837,1852555,2012357,1895444,2050380,1789210,1932156,1898948,2046841,2098171,1625335,2138533,2046655,1785464,2105080,2024935,1852446,2073682,1478644,2103660,1751154,1863254,1478332,1849259,1593399,1895334,2075182,2134365,2136657,2041203,2043944,2040358,2093521,1913544,2082455,2024959,2045812,1973980,1494485,1986446,1525605,2046849,1785194,1822210,2053401,1918823,2001794,1785258,2064339,1986338,1710198,1521244,1822292,1931276,2134370,2075073,2134300,2075068,1521210,2131493,1951008,1914649,1774999,1601557,1485584,2078975,1986330,1612190,2064410,2066054,1985760,1685075,1930273,2032161,1955161,,### loopCnt=626,loopCntPos=274,loopCntNeg=352
As it stands, your search won't pick up the first user as there won't be a preceding comma. However, I would suggest solving the problem in a far simpler manner, by using a set: public class UsersEJB implements SessionBean { private void processSelectionData { Collection userVoCollection = dc.retProjectOrgUsers(projectID, strDistributionCompID, porjectDataSource); // This is returning List of 626 UserVO Set<String> usersSet = new HashSet<String>(userVoCollection.size()); if(log.isDebugEnabled()) log.debug("UserList Size="+userVoCollection.size()+",B4 strUsers="+strUsers.toString()); for (UserVO uVO : userVoCollection) { if (usersSet.add(uVO.userID.toString()) loopCntPos++; else { loopCntNeg++; if(log.isDebugEnabled()) log.debug("UserId="+uVO.userID.toString()+",strUsers="+loopCnt+"="+strUsers.toString()); } if(log.isDebugEnabled()) log.debug("COMPANIES_ID1 strUsers=" + usersSet + ",### loopCnt="+loopCnt + ",loopCntPos="+loopCntPos + ",loopCntNeg="+loopCntNeg); } }
Jenkins/Hudson CLI API to modify the node labels using Groovy
Does anyone know how to modify the Jenkins/Hudson node labels in a non-manually way? I mean, thorough an API like the CLI API that this tool offers (without restarting Jenkins/Hudson of course). My guess is that the best option is using a Groovy script to enter into the Jenkins/Hudson guts. Executing something like: java -jar -s HUDSON_URL:8080 groovy /path/to/groovy.groovy Being the content of that script something like: for (aSlave in hudson.model.Hudson.instance.slaves) { labels = aSlave.getAssignedLabels() println labels **aSlave.setLabel("blabla")** // this method doesn't exist, is there any other way??? } Thanks in advance! Victor
Note: the other answers are a bit old, so it could be that the API has appeared since then. Node labels are accessed in the API as a single string, just like in the Configure screen. To read and write labels: Node.getLabelString() and Node.setLabelString(String). Note that you can get the effective labels as well via: Node.getAssignedLabels(), which returns a Collection of LabelAtom that includes dynamically computed labels such as the 'self-label' (representing the node name itself). Last, these methods on the Node class are directly accessible from the slave objects also, e.g. as a System Groovy Script: hudson = hudson.model.Hudson.instance hudson.slaves.findAll { it.nodeName.equals("slave4") }.each { slave -> print "Slave $slave.nodeName : Labels: $slave.labelString" slave.labelString = slave.labelString + " " + "offline" println " --> New labels: $slave.labelString" } hudson.save()
I've found a way to do this using the Groovy Postbuild Plugin. I have a Jenkins job that takes a few parameters (NodeToUpdate, LabelName, DesiredState) and executes this content in the Groovy Postbuild Plugin: nodeName = manager.envVars['NodeToUpdate'] labelName = manager.envVars['LabelName'] set = manager.envVars['DesiredState'] for (node in jenkins.model.Jenkins.instance.nodes) { if (node.getNodeName().equals(nodeName)) { manager.listener.logger.println("Found node to update: " + nodeName) oldLabelString = node.getLabelString() if (set.equals('true')) { if (!oldLabelString.contains(labelName)) { manager.listener.logger.println("Adding label '" + labelName + "' from node " + nodeName); newLabelString = oldLabelString + " " + labelName node.setLabelString(newLabelString) node.save() } else { manager.listener.logger.println("Label '" + labelName + "' already exists on node " + nodeName) } } else { if (oldLabelString.contains(labelName)) { manager.listener.logger.println("Removing label '" + labelName + "' from node " + nodeName) newLabelString = oldLabelString.replaceAll(labelName, "") node.setLabelString(newLabelString) node.save() } else { manager.listener.logger.println("Label '" + labelName + "' doesn't exist on node " + nodeName) } } } }
I've not seen a way yet to change the slave label either. I've taken to editing the main config.xml file and issuing a reload from the CLI. This has it's own problems though - any jobs currently running are lost until the next jenkins restart - see https://issues.jenkins-ci.org/browse/JENKINS-3265
Getting device/driver information related to a COM port?
I have a Serial-to-USB device with a similarly named device driver in the Windows device manager. The devices do not always grab the same COM port on system boot, so my program needs to identify it on start up. I've tried using RXTX to enumerate the COM ports on the system, but this didn't work because CommPortIdentifier.getName() simply returns the COM name (eg. COM1, COM2, etc.) I need to acquire either the driver manufacturer name, or the driver name as it appears in the device manager, and associate it with the COM name. Can this easily be done in Java? (I'd be interested in any 3rd party Java libraries that support this.) Otherwise, how I could begin to accomplish this via the win32 API?
I achieved what I wanted by using the WinRegistry class provided by David in this SO question to obtain the FriendlyName from registry key associated with my USB device. I then parse out the COM number from the friendly name. Some things to consider: USB devices are located at HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\USB\ in the registry (tested on WinXP, Win7.) I required the device VID + PID to identify the correct device key (eg. VID_xxxx&PID_xxxx.) Since VID and PID are device specific, this key should be reliable across multiple systems. The VID_xxxx&PID_xxxx key contains another sub-key with device values. I had some trouble enumerating the sub-keys with WinRegistry, so I hard-coded the sub-key name as a quick hack during development. A much safer solution would search sub-keys to find the correct name. The device keys exist in the registry regardless of whether the device is currently connected. This code makes the assumption that Windows will update FriendlyName if the device is reconnected to a different COM port. I haven't verified this, but things looked good during use-testing. Example String keyPath = "SYSTEM\\CurrentControlSet\\Enum\\USB\\Vid_067b&Pid_2303\\"; String device1 = "5&75451e6&0&1"; System.out.println("First COM device: " + getComNumber(keyPath + device1)); Code import java.util.regex.Pattern; import java.util.regex.Matcher; // Given a registry key, attempts to get the 'FriendlyName' value // Returns null on failure. // public static String getFriendlyName(String registryKey) { if (registryKey == null || registryKey.isEmpty()) { throw new IllegalArgumentException("'registryKey' null or empty"); } try { int hkey = WinRegistry.HKEY_LOCAL_MACHINE; return WinRegistry.readString(hkey, registryKey, "FriendlyName"); } catch (Exception ex) { // catch-all: // readString() throws IllegalArg, IllegalAccess, InvocationTarget System.err.println(ex.getMessage()); return null; } } // Given a registry key, attempts to parse out the integer after // substring "COM" in the 'FriendlyName' value; returns -1 on failure. // public static int getComNumber(String registryKey) { String friendlyName = getFriendlyName(registryKey); if (friendlyName != null && friendlyName.indexOf("COM") >= 0) { String substr = friendlyName.substring(friendlyName.indexOf("COM")); Matcher matchInt = Pattern.compile("\\d+").matcher(substr); if (matchInt.find()) { return Integer.parseInt(matchInt.group()); } } return -1; }
#robjb Your code does not allow for more than one device to be connected. How will the user know the device name? I added to your code thus to return a list of com ports: ArrayList<String> subKeys = WinRegistry.readStringSubKeys(WinRegistry.HKEY_LOCAL_MACHINE, keyPath); ArrayList<Integer> comPorts = new ArrayList<Integer>(); for (String subKey : subKeys) { String friendlyName = getFriendlyName(keyPath + subKey); if (friendlyName != null && friendlyName.contains("MyDriverName") && friendlyName.contains("COM")) { int beginIndex = friendlyName.indexOf("COM") + 3 /*length of 'COM'*/; int endIndex = friendlyName.indexOf(")"); comPorts.add(Integer.parseInt(friendlyName.substring(beginIndex, endIndex))); } } Update: I don't think these are solutions. Why? This information is statically stored in the registry - even when the device is not connected.
Great example, using JNA, here. The author (Geir Arne Ruud) has released it under Public Domain License. My example code public static String getFriendlyName(GoGPSModel model, String name) { if(model.getSystem().getOSType() != OSType.Windows32 && model.getSystem().getOSType() != OSType.Windows64) { return name; } for (DeviceInformation devInfo : infoObjects) { System.out.println(devInfo.toString()); String friendlyName = devInfo.getFriendlyName(); if(friendlyName != null && !friendlyName.equals("") && friendlyName.contains(name)) { return devInfo.getManufacturer() + ": " + friendlyName; } } return name; }
Is it possible to get a list of workflows the document is attached to in Alfresco
I'm trying to get a list of workflows the document is attached to in an Alfresco webscript, but I am kind of stuck. My original problem is that I have a list of files, and the current user may have workflows assigned to him with these documents. So, now I want to create a webscript that will look in a folder, take all the documents there, and assemble a list of documents together with task references, if there are any for the current user. I know about the "workflow" object that gives me the list of workflows for the current user, but this is not a solution for my problem. So, can I get a list of workflows a specific document is attached to?
Well, for future reference, I've found a way to get all the active workflows on a document from javascript: var nodeR = search.findNode('workspace://SpacesStore/'+doc.nodeRef); for each ( wf in nodeR.activeWorkflows ) { // Do whatever here. }
I used packageContains association to find workflows for document. Below i posted code in Alfresco JavaScript for active workflows (as zladuric answered) and also for all workflows: /*global search, logger, workflow*/ var getWorkflowsForDocument, getActiveWorkflowsForDocument; getWorkflowsForDocument = function () { "use strict"; var doc, parentAssocs, packages, packagesLen, i, pack, props, workflowId, instance, isActive; // doc = search.findNode("workspace://SpacesStore/8847ea95-108d-4e08-90ab-34114e7b3977"); parentAssocs = doc.getParentAssocs(); packages = parentAssocs["{http://www.alfresco.org/model/bpm/1.0}packageContains"]; // if (packages) { packagesLen = packages.length; // for (i = 0; i < packagesLen; i += 1) { pack = packages[i]; props = pack.getProperties(); workflowId = props["{http://www.alfresco.org/model/bpm/1.0}workflowInstanceId"]; instance = workflow.getInstance(workflowId); /* instance is org.alfresco.repo.workflow.jscript.JscriptWorkflowInstance */ isActive = instance.isActive(); logger.log(" + instance: " + workflowId + " (active: " + isActive + ")"); } } }; getActiveWorkflowsForDocument = function () { "use strict"; var doc, activeWorkflows, activeWorkflowsLen, i, instance; // doc = search.findNode("workspace://SpacesStore/8847ea95-108d-4e08-90ab-34114e7b3977"); activeWorkflows = doc.activeWorkflows; activeWorkflowsLen = activeWorkflows.length; for (i = 0; i < activeWorkflowsLen; i += 1) { instance = activeWorkflows[i]; /* instance is org.alfresco.repo.workflow.jscript.JscriptWorkflowInstance */ logger.log(" - instance: " + instance.getId() + " (active: " + instance.isActive() + ")"); } } getWorkflowsForDocument(); getActiveWorkflowsForDocument();
Unfortunately the javascript API doesn't expose all the workflow functions. It look like getting the list of workflow instances that are attached to a document only works in Java (or Java backed webscripts). List<WorkflowInstance> workflows = workflowService.getWorkflowsForContent(node.getNodeRef(), true); A usage of this can be found in the workflow list in the document details: http://svn.alfresco.com/repos/alfresco-open-mirror/alfresco/HEAD/root/projects/web-client/source/java/org/alfresco/web/ui/repo/component/UINodeWorkflowInfo.java To get to the users who have tasks assigned you would then need to use getWorkflowPaths and getTasksForWorkflowPath methods of the WorkflowService.
Using Java, How can I get a list of all local users on a windows machine
How can I list all the local users configured on a windows machine (Win2000+) using java. I would prefer doing this with ought using any java 2 com bridges, or any other third party library if possible. Preferable some native method to Java.
Using a Java-COM Bridge , like Jacob. You then select an appropriate COM library, e.g. COM API for WMI to list local users, or any other Windows management information. The Win32_SystemUsers association WMI class relates a computer system and a user account on that system. The Win32_Account abstract WMI class contains information about user accounts and group accounts known to the computer system running Windows. User or group names recognized by a Windows NT domain are descendants (or members) of this class. Working Example (jacob 1.17-M2, javaSE-1.6): import java.util.Enumeration; import com.jacob.activeX.ActiveXComponent; import com.jacob.com.ComThread; import com.jacob.com.EnumVariant; import com.jacob.com.Variant; public class ComTst { public static void main(String[] args) { ComThread.InitMTA(); try { ActiveXComponent wmi = new ActiveXComponent("winmgmts:\\\\."); Variant instances = wmi.invoke("InstancesOf", "Win32_SystemUsers"); Enumeration<Variant> en = new EnumVariant(instances.getDispatch()); while (en.hasMoreElements()) { ActiveXComponent bb = new ActiveXComponent(en.nextElement().getDispatch()); System.out.println(bb.getPropertyAsString("PartComponent")); } } finally { ComThread.Release(); } } }
Using Java COM Object, i.e. Jacob: public static void EnumerateUsers() { String query = "SELECT * FROM Win32_UserAccount"; ActiveXComponent axWMI = new ActiveXComponent("winmgmts:\\"); Variant vCollection = axWMI.invoke("ExecQuery", new Variant(query)); EnumVariant enumVariant = new EnumVariant(vCollection.toDispatch()); Dispatch item = null; StringBuilder sb = new StringBuilder(); while (enumVariant.hasMoreElements()) { item = enumVariant.nextElement().toDispatch(); sb.append("User: " + Dispatch.call(item, "Name")).toString(); System.out.println(sb); sb.setLength(0); } }
There is a simpler solution for what I needed. This implementation will use the "net user" command to get the list of all users on a machine. This command has some formatting which in my case I don't care about, I only care if my user is in the list or not. If some one needs the actual user list, he can parse the output format of "net user" to extract the list without the junk headers and footers generated by "net use" private boolean isUserPresent() { //Load user list ProcessBuilder processBuilder = new ProcessBuilder("net","user"); processBuilder.redirectErrorStream(true); String output = runProcessAndReturnOutput(processBuilder); //Check if user is in list //We assume the output to be a list of users with the net user //Remove long space sequences output = output.replaceAll("\\s+", " ").toLowerCase(); //Locate user name in resulting list String[] tokens = output.split(" "); Arrays.sort(tokens); if (Arrays.binarySearch(tokens, "SomeUserName".toLowerCase()) >= 0){ //We found the user name return true; } return false; } The method runProcessAndReturnOutput runs the process, collects the stdout and stderr of the process and returns it to the caller.
import com.sun.jna.platform.win32.Netapi32Util; Netapi32Util.User[] users = Netapi32Util.getUsers(); for(Netapi32Util.User user : users) { System.out.println(user.name); }