int CreateServiceSettingsAction::ExecuteAction(const Argz* az, const ServiceTaskSettings* baseSettings) {  
  CString serviceCommand;
  CString logFile;
  {    
    int ret = ServiceAction().GenerateServiceCommandLine(az, serviceCommand, logFile);
    if (ret != 0) return ret;
  }

  if (logFile.GetLength() > 0) {
    LOG.LogInfoFormat(L"Service log file is set to: %s", logFile);
  }
  
  SimpleCreateServiceSettings settings(baseSettings, serviceCommand);

  if (az->HasArgument(L"/runAsSystem")) {
    settings.setRunAsSystem(true);
    LOG.LogInfo(L"Installing service unser LOCAL_SYSTEM account");
  } else {
    int ret = ParseUserSettings(az, &settings);
    if (ret != 0) return ret;
    LOG.LogInfoFormat(L"Installing service under %s (domain=%s) account", settings.getUserName(), settings.getDomain());
  }

  settings.setAutostart(az->GetBooleanArgument(L"autostart", true) && az->GetBooleanArgument(KEY_AUTORUN, true));

  return ExecuteAction(az, &settings, baseSettings);  
}
 virtual int executeCommand(LSA_HANDLE lsa, PSID sid) {
   LPTSTR sSid;
   if (0 == ConvertSidToStringSid(sid, &sSid)) {
     LOG.LogErrorFormat(L"Failed to convert SID to string. %s", LOG.GetLastError());
     return 1;
   }
   LOG.LogInfoFormat(L"User token opened: SID=%s", sSid);
   LocalFree(sSid);
   return 0;
 }
int CreateServiceCommand::executeCommand(SC_HANDLE scm) {
  LOG.LogDebugFormat(L"Creating and registering service: name=%s...", mySettings->getServiceName());
  
  CString sUserName = CreateFormatted(L"%s\\%s", mySettings->getDomain(), mySettings->getUserName());
  CString sPassword = mySettings->getPassword();

  LPCWSTR userName = NULL;
  LPCWSTR password = NULL;

  if (!mySettings->runAsSystem()) {
    //use declared variables to avoid strings from distruct
    userName = sUserName;
    password = sPassword;
    LOG.LogInfoFormat(L"Installing service for user: %s", userName);
  }

  SC_HANDLE service = CreateService(
    scm, //ServiceControlManager instance
    mySettings->getServiceName(),
    mySettings->getServiceDisplayName(),
    SERVICE_ALL_ACCESS, //any option here?
    SERVICE_WIN32_OWN_PROCESS, //Consider to have SERVICE_INTERACTIVE_PROCESS
    mySettings->isAutostart() ? SERVICE_AUTO_START : SERVICE_DEMAND_START, 
    SERVICE_ERROR_NORMAL, 
    mySettings->getServiceExecutable(), //executable command    
    NULL, //Start orger group
    NULL, //tag
    NULL, //dependencies
    userName,
    password
  );

  if (service == NULL) {
    DWORD err = GetLastError();
    CString msg = CreateFormatted(L"Failed to create service %s.", mySettings->getServiceName());
    switch(err) {
    case ERROR_ACCESS_DENIED:
      LOG.LogWarnFormat(L"%s Access denied", msg);
      return 1;
    case ERROR_CIRCULAR_DEPENDENCY:
      LOG.LogWarnFormat(L"%s A circular service dependency was specified", msg);
      return 1;
    case ERROR_DUPLICATE_SERVICE_NAME:
      LOG.LogWarnFormat(L"%s Service display name is already used", msg);
      return 1;
    case ERROR_INVALID_NAME:
      LOG.LogWarnFormat(L"%s The specified service name is invalid", msg);
      return 1;
    case ERROR_INVALID_PARAMETER:
      LOG.LogWarnFormat(L"%s A parameter that was specified is invalid", msg);
      return 1;
    case ERROR_INVALID_SERVICE_ACCOUNT:
      LOG.LogWarnFormat(L"%s Specified account does not exist", msg);
      return 1;
    case ERROR_SERVICE_EXISTS:
      LOG.LogWarnFormat(L"%s The service already exists", msg);
      return 1;
    case ERROR_SERVICE_MARKED_FOR_DELETE:
      LOG.LogWarnFormat(L"%s The service already exists and marked for deletion", msg);
      return 1;
    case ERROR_INVALID_HANDLE:
    default:
      LOG.LogErrorFormat(L"%s %s", msg, LOG.GetLastError());
      return 1;
    }    
  }

  LOG.LogInfoFormat(L"Service '%s' was created", mySettings->getServiceName());
  updateServiceDescription();

  CloseServiceHandle(service);

  return 0;
}