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.JIException;
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. If a service has dependents, the
* dependent services are also stopped/started.
*
* @version $Revision: $
* @author $Author: $
*/
public class ServiceManager {
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.
ServiceManager manager = new ServiceManager();
manager.start(domain, hostname, username, password, "Print Spooler");
}
/**
* 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.
*
* <p/>
*
* <strong>NOTE:</strong> serviceName is the internal short 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 Caption = '" + 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));
// JIVariant countVariant = wbemObjectSet.get("Count");
// int numberOfServices = countVariant.getObjectAsInt();
// System.out.print(numberOfServices);
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);
System.out.println(ErrorCodes.SERVICE_ERRORS.get(returnStatus.getObjectAsInt()));
// Attempt to stop dependent services
if (returnStatus.getObjectAsInt() == 3 || returnStatus.getObjectAsInt() == 13) {
manageDependents(wbemServices, serviceName, action);
returnStatus = wbemObjectDispatch.callMethodA("StopService");
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();
}
}
}
}
/**
* Starts or Stops dependent services
*
* @param wbemServices
* @param parent
* @param action
* @throws JIException
*/
protected void manageDependents(IJIDispatch wbemServices, String parent, int action) throws JIException {
final int RETURN_IMMEDIATE = 0x10;
final int FORWARD_ONLY = 0x20;
Object[] params = new Object[] {
new JIString("Associators of {Win32_Service.Name='" + parent
+ "'} Where AssocClass=Win32_DependentService Role=Antecedent"),
JIVariant.OPTIONAL_PARAM(),
new JIVariant(new Integer(RETURN_IMMEDIATE + FORWARD_ONLY)) };
JIVariant[] dependentsSet = wbemServices.callMethodA("ExecQuery", params);
IJIDispatch wbemObjectSet = (IJIDispatch) narrowObject(dependentsSet[0].getObjectAsComObject());
// JIVariant countVariant = wbemObjectSet.get("Count");
// int numberOfServices = countVariant.getObjectAsInt();
// System.out.print("Number of dependents: " + numberOfServices);
JIVariant newEnumvariant = wbemObjectSet.get("_NewEnum");
IJIComObject enumComObject = newEnumvariant.getObjectAsComObject();
IJIEnumVariant enumVariant = (IJIEnumVariant) narrowObject(enumComObject.queryInterface(IJIEnumVariant.IID));
for (int i = 0; i < 20; i++) {
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());
// Start or Stop the servie
String methodToInvoke = (action == START) ? "StartService" : "StopService";
JIVariant returnStatus = wbemObjectDispatch.callMethodA(methodToInvoke);
System.out.println(ErrorCodes.SERVICE_ERRORS.get(returnStatus.getObjectAsInt()));
}
}
}
/**
* 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;
}
}