/// <summary> /// Installs and optionally starts the service. /// </summary> /// <param name="path">The full path of the service exe.</param> /// <param name="name">The name of the service.</param> /// <param name="displayName">The display name of the service.</param> /// <param name="description">The description for the service.</param> /// <param name="startMode">The service start mode.</param> /// <param name="userName">The account name. Null to use the default account (LocalSystem).</param> /// <param name="password">The account password.</param> /// <param name="start">True to start the service after the installation; otherwise, false. /// Once the method returns you can use this parameter to check whether the service is running or not.</param> /// <param name="dependencies">The list of dependencies services. Null if there are no dependencies.</param> /// <returns>True for success. Otherwise, false.</returns> public static bool InstallService( string path, string name, string displayName, string description, StartMode startMode, string userName, string password, ref bool start, string[] dependencies) { uint SC_MANAGER_CREATE_SERVICE = 0x0002; if (string.IsNullOrEmpty(userName)) { userName = null; password = null; } // check if an existing service needs to uninstalled. try { Service existingService = ServiceManager.GetService(name); if (existingService != null) { if (existingService.StartMode != StartMode.Disabled && existingService.Path == path) { if (existingService.Status == ServiceStatus.Stopped) { ServiceManager.StartService(name); } return(true); } UnInstallService(name); } } catch (Exception e) { Utils.Trace(e, "CreateService Exception"); } IntPtr svHandle = IntPtr.Zero; try { IntPtr scHandle = OpenSCManagerW(null, null, SC_MANAGER_CREATE_SERVICE); if (scHandle.ToInt64() != 0) { string dependencyServices = string.Empty; if (dependencies != null && dependencies.Length > 0) { for (int i = 0; i < dependencies.Length; i++) { if (!string.IsNullOrEmpty(dependencies[i])) { dependencyServices += dependencies[i].Trim(); if (i < dependencies.Length - 1) { dependencyServices += "\0";//add a null char separator } } } } if (dependencyServices == string.Empty) { dependencyServices = null; } // lpDependencies, if not null, must be a series of strings concatenated with the null character as a delimiter, including a trailing one. svHandle = CreateServiceW( scHandle, name, displayName, (uint)ServiceAccess.AllAccess, (uint)ServiceType.OwnProcess, (uint)startMode, (uint)ServiceError.ErrorNormal, path, null, 0, dependencyServices, userName, password); if (svHandle.ToInt64() == 0) { int error = GetLastError(); Utils.Trace("CreateService Error: {0}", error); return(false); } // set the description. if (!String.IsNullOrEmpty(description)) { SERVICE_DESCRIPTION info = new SERVICE_DESCRIPTION(); info.lpDescription = description; IntPtr pInfo = Marshal.AllocCoTaskMem(Marshal.SizeOf(typeof(SERVICE_DESCRIPTION))); Marshal.StructureToPtr(info, pInfo, false); try { int result = ChangeServiceConfig2W(svHandle, SERVICE_CONFIG_DESCRIPTION, pInfo); if (result == 0) { Utils.Trace("Could not set description for service: {0}", displayName); } } finally { Marshal.DestroyStructure(pInfo, typeof(SERVICE_DESCRIPTION)); Marshal.FreeCoTaskMem(pInfo); } } // start the service. if (start) { start = ServiceManager.StartService(name, new TimeSpan(0, 0, 0, 60)); } return(true); } } catch (Exception e) { Utils.Trace(e, "CreateService Exception"); } finally { SafeCloseServiceHandle(svHandle); } return(false); }