Hello on Windows 7 , i tried to make new service with help of sigar api.
But there seems much bug.
Below code is not working.
I always got error file path is wrong.
I changed paths even checked all bytes of my strings but it did not solve my problem.
I've looked lpBinaryPathName
MSDN Says:
The fully qualified path to the service binary file. If the path contains a space, it must be quoted so that it is correctly interpreted. For example, "d:\\my share\\myservice.exe" should be specified as "\"d:\\my share\\myservice.exe\"".
But also changing path to that kind of solution did not solve my problem.
On Windows MSDN docs says about CreateService :
http://msdn.microsoft.com/en-us/library/windows/desktop/ms682450(v=vs.85).aspx
try {
ServiceConfig sc = new ServiceConfig("minercontroller");
sc.setDescription("Miner Controller");
//List configs = Service.getServiceConfigs( sigar, "svchost.exe");
try {
String str = getWorkingDirectory().getCanonicalPath()+"\\minerFile";
//"\"C:\Program Files\CollabNet Subversion Server\svnserve.exe\"
String val = "\"\\\"C:\\\\test.exe\\\"";
System.out.println(val);
str = "\"C:\\test.exe\"";
sc.setPath(str);
JOptionPane.showMessageDialog(null,str);
} catch (IOException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
}
sc.setStartName("Kadir Deneme");
//config.setStartType(ServiceConfig.START_MANUAL);
sc.setDisplayName("My Test Service");
//wrapper.ntservice.account=NT AUTHORITY\NetworkService
//wrapper.ntservice.account=NT AUTHORITY\LocalService
//.\\Administrator
sc.setName( ".\\bayner" );
//sc.setPassword("123456");
sc.setType(ServiceConfig.TYPE_WIN32_OWN_PROCESS);
sc.setErrorControl( ServiceConfig.ERROR_IGNORE );
sc.list( System.out );
//"C:\\Program Files\\My Test 1.0\\mytest.exe"
sc.setStartType(ServiceConfig.START_MANUAL);
Service service = Service.create(sc);
service.start();
int status = service.getStatus();
JOptionPane.showMessageDialog(null,String.valueOf(status));
} catch (Win32Exception e) {
JOptionPane.showMessageDialog(null,e.getMessage());
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
}
So after trying to create service all day with sigar failed.I finally moved to JNA temporary.
My solution became like this:
@Override
public void putOnStartup(String serviceName,String path, String description) {
Pointer pointer = Advapi32.INSTANCE.OpenSCManager(null,null, Advapi32.SC_MANAGER_ALL_ACCESS );
Pointer result = Advapi32.INSTANCE.CreateService( pointer , serviceName ,
description , Advapi32.SERVICE_ALL_ACCESS , Advapi32.SERVICE_WIN32_OWN_PROCESS ,
Advapi32.SERVICE_AUTO_START , Advapi32.SERVICE_ERROR_IGNORE , path , null , null , null , null , null );
if(result != null) {
Advapi32.SERVICE_DESCRIPTION desc = new Advapi32.SERVICE_DESCRIPTION();
boolean success = Advapi32.INSTANCE.ChangeServiceConfig2(result, 1 , desc);
if(!success) {
JPanel panel = new JPanel();
panel.setLayout(new GridLayout( 2 , 2 ));
JLabel label = new JLabel("Enter a password:");
JPasswordField pass = new JPasswordField(10);
panel.add(label);
panel.add(pass);
JLabel label2 = new JLabel("Enter UserName:");
JTextField pass2 = new JTextField(10);
panel.add(label2);
panel.add(pass2);
panel.add(label);
panel.add(pass);
String[] options = new String[]{"OK", "Cancel"};
int option = JOptionPane.showOptionDialog(null, panel, "Windows Password",
JOptionPane.NO_OPTION, JOptionPane.PLAIN_MESSAGE,
null, options, options[1]);
if(option == 0) // pressing OK button
{
char[] password = pass.getPassword();
String strPassword = new String(password);
String userName = pass2.getText();
Advapi32.INSTANCE.CreateService( pointer , SERVICE_NAME ,
description , Advapi32.SERVICE_ALL_ACCESS , Advapi32.SERVICE_WIN32_OWN_PROCESS ,
Advapi32.SERVICE_AUTO_START , Advapi32.SERVICE_ERROR_IGNORE , path , null , null , null , null , null );
}
}
Advapi32.INSTANCE.CloseServiceHandle(result);
}
}
package os.win;
import com.sun.jna.Native;
import com.sun.jna.Pointer;
import com.sun.jna.Structure;
import com.sun.jna.WString;
import com.sun.jna.platform.win32.WinReg;
import com.sun.jna.ptr.IntByReference;
import com.sun.jna.win32.StdCallLibrary;
import com.sun.jna.win32.W32APIOptions;
import java.util.Arrays;
import java.util.List;
/**
* Created with IntelliJ IDEA.
* User: bayner
* Date: 12.11.2012 a
* Time: 10:29
* To change this template use File | Settings | File Templates.
*/
public interface Advapi32 extends StdCallLibrary {
public static final int SC_MANAGER_ALL_ACCESS = (0xF003F);
public static final int SERVICE_ALL_ACCESS = (0xF01FF);
public static final int SERVICE_WIN32_OWN_PROCESS = 0x00000010;
public static final int SERVICE_AUTO_START = 0x00000002;
public static final int SERVICE_ERROR_IGNORE = 0x00000000;
Advapi32 INSTANCE = (Advapi32) Native.loadLibrary("Advapi32", Advapi32.class,W32APIOptions.UNICODE_OPTIONS);
public Pointer OpenSCManager(String lpMachineName, WString lpDatabaseName, int dwDesiredAccess);
public boolean CloseServiceHandle(Pointer hSCObject);
public boolean StartService(Pointer hService, int dwNumServiceArgs, char[] lpServiceArgVectors);
public Pointer CreateService(Pointer hSCManager, String lpServiceName, String lpDisplayName,
int dwDesiredAccess, int dwServiceType, int dwStartType, int dwErrorControl,
String lpBinaryPathName, String lpLoadOrderGroup, IntByReference lpdwTagId,
String lpDependencies, String lpServiceStartName, String lpPassword);
public boolean DeleteService(Pointer hService);
public boolean ChangeServiceConfig2(Pointer hService, int dwInfoLevel, ChangeServiceConfig2Info lpInfo);
public static class ChangeServiceConfig2Info extends Structure {
@Override
protected List getFieldOrder() {
return null;
}
}
public static class SERVICE_DESCRIPTION extends ChangeServiceConfig2Info {
public String lpDescription;
@Override
protected List getFieldOrder() {
return Arrays.asList(new String[] {"lpDescription"});
}
}
}