TCHAR command[MAX_PATH];\r
GetModuleFileName(0, command, _countof(command));\r
\r
+ /* Startup type. */\r
+ unsigned long startup;\r
+ switch (service->startup) {\r
+ case NSSM_STARTUP_MANUAL: startup = SERVICE_DEMAND_START; break;\r
+ case NSSM_STARTUP_DISABLED: startup = SERVICE_DISABLED; break;\r
+ default: startup = SERVICE_AUTO_START;\r
+ }\r
+\r
+ /* Display name. */\r
+ if (! service->displayname[0]) _sntprintf_s(service->displayname, _countof(service->displayname), _TRUNCATE, _T("%s"), service->name);\r
+\r
/* Create the service */\r
- service->handle = CreateService(services, service->name, service->name, SC_MANAGER_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS, SERVICE_AUTO_START, SERVICE_ERROR_NORMAL, command, 0, 0, 0, 0, 0);\r
+ service->handle = CreateService(services, service->name, service->displayname, SC_MANAGER_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS, startup, SERVICE_ERROR_NORMAL, command, 0, 0, 0, 0, 0);\r
if (! service->handle) {\r
print_message(stderr, NSSM_MESSAGE_CREATESERVICE_FAILED);\r
CloseServiceHandle(services);\r
return 5;\r
}\r
\r
+ if (service->description[0]) {\r
+ SERVICE_DESCRIPTION description;\r
+ ZeroMemory(&description, sizeof(description));\r
+ description.lpDescription = service->description;\r
+ if (! ChangeServiceConfig2(service->handle, SERVICE_CONFIG_DESCRIPTION, &description)) {\r
+ log_event(EVENTLOG_ERROR_TYPE, NSSM_EVENT_SERVICE_CONFIG_DESCRIPTION_FAILED, service->name, error_string(GetLastError()), 0);\r
+ }\r
+ }\r
+\r
+ if (service->startup == NSSM_STARTUP_DELAYED) {\r
+ SERVICE_DELAYED_AUTO_START_INFO delayed;\r
+ ZeroMemory(&delayed, sizeof(delayed));\r
+ delayed.fDelayedAutostart = 1;\r
+ /* Delayed startup isn't supported until Vista. */\r
+ if (! ChangeServiceConfig2(service->handle, SERVICE_CONFIG_DELAYED_AUTO_START_INFO, &delayed)) {\r
+ unsigned long error = GetLastError();\r
+ /* Pre-Vista we expect to fail with ERROR_INVALID_LEVEL */\r
+ if (error != ERROR_INVALID_LEVEL) {\r
+ log_event(EVENTLOG_ERROR_TYPE, NSSM_EVENT_SERVICE_CONFIG_DELAYED_AUTO_START_INFO_FAILED, service->name, error_string(error), 0);\r
+ }\r
+ }\r
+ }\r
+\r
/* Now we need to put the parameters into the registry */\r
if (create_parameters(service)) {\r
print_message(stderr, NSSM_MESSAGE_CREATE_PARAMETERS_FAILED);\r
unsigned long error = GetLastError();\r
/* Pre-Vista we expect to fail with ERROR_INVALID_LEVEL */\r
if (error != ERROR_INVALID_LEVEL) {\r
- log_event(EVENTLOG_ERROR_TYPE, NSSM_EVENT_CHANGESERVICECONFIG2_FAILED, service->name, error_string(error), 0);\r
+ log_event(EVENTLOG_ERROR_TYPE, NSSM_EVENT_SERVICE_CONFIG_FAILURE_ACTIONS_FAILED, service->name, error_string(error), 0);\r
}\r
}\r
}\r
flags |= CREATE_UNICODE_ENVIRONMENT;\r
#endif\r
if (! CreateProcess(0, cmd, 0, 0, inherit_handles, flags, service->env, service->dir, &si, &pi)) {\r
+ unsigned long exitcode = 3;\r
unsigned long error = GetLastError();\r
- if (error == ERROR_INVALID_PARAMETER && service->env) log_event(EVENTLOG_ERROR_TYPE, NSSM_EVENT_CREATEPROCESS_FAILED_INVALID_ENVIRONMENT, service->name, service->exe, NSSM_REG_ENV, 0);\r
+ if (error == ERROR_INVALID_PARAMETER && service->env) {\r
+ log_event(EVENTLOG_ERROR_TYPE, NSSM_EVENT_CREATEPROCESS_FAILED_INVALID_ENVIRONMENT, service->name, service->exe, NSSM_REG_ENV, 0);\r
+ if (test_environment(service->env)) exitcode = 4;\r
+ }\r
else log_event(EVENTLOG_ERROR_TYPE, NSSM_EVENT_CREATEPROCESS_FAILED, service->name, service->exe, error_string(error), 0);\r
close_output_handles(&si);\r
- return stop_service(service, 3, true, true);\r
+ return stop_service(service, exitcode, true, true);\r
}\r
service->process_handle = pi.hProcess;\r
service->pid = pi.dwProcessId;\r
}\r
\r
if (default_action && ! exitcode && ! graceful) {\r
- log_event(EVENTLOG_INFORMATION_TYPE, NSSM_EVENT_GRACEFUL_SUICIDE, service->name, service->exe, exit_action_strings[NSSM_EXIT_UNCLEAN], exit_action_strings[NSSM_EXIT_UNCLEAN], exit_action_strings[NSSM_EXIT_UNCLEAN], exit_action_strings[NSSM_EXIT_REALLY] ,0);\r
+ log_event(EVENTLOG_INFORMATION_TYPE, NSSM_EVENT_GRACEFUL_SUICIDE, service->name, service->exe, exit_action_strings[NSSM_EXIT_UNCLEAN], exit_action_strings[NSSM_EXIT_UNCLEAN], exit_action_strings[NSSM_EXIT_UNCLEAN], exit_action_strings[NSSM_EXIT_REALLY], 0);\r
graceful = true;\r
}\r
\r