The problem exists. Need to install the service on your computer. And run it. The code works, but when the program is run by an administrator. Here is my source code:
namespace SvcInstaller
{
public class ServiceInstaller
{
#region Private Variables
/* bla bla bla */
#endregion DLLImport
#region Main method + testing code
[STAThread]
public static void Setup()
{
// TODO: Add code to start application here
#region Testing
// Testing --------------
string svcPath;
string svcName;
string svcDispName;
//path to the service that you want to install
svcPath = "\"" + AppDomain.CurrentDomain.BaseDirectory + "data\\ma.exe\"" + " -service";
svcDispName = "Main Service";
svcName = "srv";
ServiceInstaller c = new ServiceInstaller();
c.InstallService(svcPath, svcName, svcDispName);
#endregion Testing
}
#endregion Main method + testing code - Commented
public bool InstallService(string svcPath, string svcName, string svcDispName)
{
#region Constants declaration.
int SC_MANAGER_CREATE_SERVICE = 0x0002;
int SERVICE_WIN32_OWN_PROCESS = 0x00000010;
//int SERVICE_DEMAND_START = 0x00000003;
int SERVICE_ERROR_NORMAL = 0x00000001;
int STANDARD_RIGHTS_REQUIRED = 0xF0000;
int SERVICE_QUERY_CONFIG = 0x0001;
int SERVICE_CHANGE_CONFIG = 0x0002;
int SERVICE_QUERY_STATUS = 0x0004;
int SERVICE_ENUMERATE_DEPENDENTS = 0x0008;
int SERVICE_START = 0x0010;
int SERVICE_STOP = 0x0020;
int SERVICE_PAUSE_CONTINUE = 0x0040;
int SERVICE_INTERROGATE = 0x0080;
int SERVICE_USER_DEFINED_CONTROL = 0x0100;
int SERVICE_ALL_ACCESS = (STANDARD_RIGHTS_REQUIRED |
SERVICE_QUERY_CONFIG |
SERVICE_CHANGE_CONFIG |
SERVICE_QUERY_STATUS |
SERVICE_ENUMERATE_DEPENDENTS |
SERVICE_START |
SERVICE_STOP |
SERVICE_PAUSE_CONTINUE |
SERVICE_INTERROGATE |
SERVICE_USER_DEFINED_CONTROL);
// int SERVICE_AUTO_START = 0x00000002;
int SERVICE_DEMAND_START = 0x00000003;// с ручной запуск
#endregion Constants declaration.
try
{
IntPtr sc_handle = OpenSCManager(null, null, SC_MANAGER_CREATE_SERVICE);
if (sc_handle.ToInt32() != 0)
{
//IntPtr sv_handle = CreateService(sc_handle, svcName, svcDispName, SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS, SERVICE_AUTO_START, SERVICE_ERROR_NORMAL, svcPath, null, 0, null, null, null);
string lpDependencies = "Tcpip";// зависимости
IntPtr sv_handle = CreateService(sc_handle, svcName, svcDispName, SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS, SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL, svcPath, null, 0, lpDependencies, null, null);
if (sv_handle.ToInt32() == 0)
{
CloseServiceHandle(sc_handle);
return false;
}
else
{
//now trying to start the service
int i = StartService(sv_handle, 0, null);
// If the value i is zero, then there was an error starting the service.
// note: error may arise if the service is already running or some other problem.
if (i == 0)
{
//Console.WriteLine("Couldnt start service");
return false;
}
CloseServiceHandle(sc_handle);
return true;
}
}
else
//Console.WriteLine("SCM not opened successfully");
return false;
}
catch (Exception e)
{
throw e;
}
}
Return code is 0 in the function. The challenge is to establish a service that does not matter who started the program.
Calling
OpenSCManagerwith theSC_MANAGER_CREATE_SERVICEflag requires administrator access.From MSDN:
If you think about it, it makes sense that you would need admin rights to install a new service.