コード例 #1
0
        public override void Install(IDictionary stateSaver)
        {
            base.Context.LogMessage(Res.GetString("InstallingService", new object[] { this.ServiceName }));
            try
            {
                CheckEnvironment();
                string servicesStartName = null;
                string password = null;
                ServiceProcessInstaller parent = null;
                if (base.Parent is ServiceProcessInstaller)
                {
                    parent = (ServiceProcessInstaller)base.Parent;
                }
                else
                {
                    for (int j = 0; j < base.Parent.Installers.Count; j++)
                    {
                        if (base.Parent.Installers[j] is ServiceProcessInstaller)
                        {
                            parent = (ServiceProcessInstaller)base.Parent.Installers[j];
                            break;
                        }
                    }
                }
                if (parent == null)
                {
                    throw new InvalidOperationException(Res.GetString("NoInstaller"));
                }
                switch (parent.Account)
                {
                    case ServiceAccount.LocalService:
                        servicesStartName = @"NT AUTHORITY\LocalService";
                        break;

                    case ServiceAccount.NetworkService:
                        servicesStartName = @"NT AUTHORITY\NetworkService";
                        break;

                    case ServiceAccount.User:
                        servicesStartName = parent.Username;
                        password = parent.Password;
                        break;
                }
                string binaryPath = base.Context.Parameters["assemblypath"];
                if ((binaryPath == null) || (binaryPath.Length == 0))
                {
                    throw new InvalidOperationException(Res.GetString("FileName"));
                }
                binaryPath = "\"" + binaryPath + "\"";
                if (!string.IsNullOrEmpty(m_commandLineOptions)) binaryPath += " " + m_commandLineOptions;
                if (!ValidateServiceName(this.ServiceName))
                {
                    object[] args = new object[] { this.ServiceName, 80.ToString(CultureInfo.CurrentCulture) };
                    throw new InvalidOperationException(Res.GetString("ServiceName", args));
                }
                if (this.DisplayName.Length > 0xff)
                {
                    throw new ArgumentException(Res.GetString("DisplayNameTooLong", new object[] { this.DisplayName }));
                }
                string dependencies = null;
                if (this.ServicesDependedOn.Length > 0)
                {
                    StringBuilder builder = new StringBuilder();
                    for (int k = 0; k < this.ServicesDependedOn.Length; k++)
                    {
                        string name = this.ServicesDependedOn[k];
                        try
                        {
                            ServiceController controller = new ServiceController(name, ".");
                            name = controller.ServiceName;
                        }
                        catch
                        {
                        }
                        builder.Append(name);
                        builder.Append('\0');
                    }
                    builder.Append('\0');
                    dependencies = builder.ToString();
                }
                IntPtr databaseHandle = SafeNativeMethods.OpenSCManager(null, null, 0xf003f);
                IntPtr zero = IntPtr.Zero;
                if (databaseHandle == IntPtr.Zero)
                {
                    throw new InvalidOperationException(Res.GetString("OpenSC", new object[] { "." }), new Win32Exception());
                }
                int serviceType = 0x10;
                int num4 = 0;
                for (int i = 0; i < base.Parent.Installers.Count; i++)
                {
                    if (base.Parent.Installers[i] is ServiceInstallerEx)
                    {
                        num4++;
                        if (num4 > 1)
                        {
                            break;
                        }
                    }
                }
                if (num4 > 1)
                {
                    serviceType = 0x20;
                }
                try
                {
                    zero = NativeMethods.CreateService(databaseHandle, this.ServiceName, this.DisplayName, 0xf01ff, serviceType, (int)this.StartType, 1, binaryPath, null, IntPtr.Zero, dependencies, servicesStartName, password);
                    if (zero == IntPtr.Zero)
                    {
                        throw new Win32Exception();
                    }
                    if (this.Description.Length != 0)
                    {
                        NativeMethods.SERVICE_DESCRIPTION serviceDesc = new NativeMethods.SERVICE_DESCRIPTION();
                        serviceDesc.description = Marshal.StringToHGlobalUni(this.Description);
                        bool flag = NativeMethods.ChangeServiceConfig2(zero, 1, ref serviceDesc);
                        Marshal.FreeHGlobal(serviceDesc.description);
                        if (!flag)
                        {
                            throw new Win32Exception();
                        }
                    }
                    stateSaver["installed"] = true;
                }
                finally
                {
                    if (zero != IntPtr.Zero)
                    {
                        SafeNativeMethods.CloseServiceHandle(zero);
                    }
                    SafeNativeMethods.CloseServiceHandle(databaseHandle);
                }
                base.Context.LogMessage(Res.GetString("InstallOK", new object[] { this.ServiceName }));
            }
            finally
            {
                base.Install(stateSaver);
            }
        }
コード例 #2
0
ファイル: ServiceInstaller.cs プロジェクト: zyj0021/Topshelf
        /// <summary>Installs the service by writing service application information to the registry. This method is meant to be used by installation tools, which process the appropriate methods automatically.</summary>
        /// <param name="stateSaver">An <see cref="T:System.Collections.IDictionary" /> that contains the context information associated with the installation. </param>
        /// <exception cref="T:System.InvalidOperationException">The installation does not contain a <see cref="T:System.ServiceProcess.ServiceProcessInstaller" /> for the executable.-or- The file name for the assembly is null or an empty string.-or- The service name is invalid.-or- The Service Control Manager could not be opened. </exception>
        /// <exception cref="T:System.ArgumentException">The display name for the service is more than 255 characters in length.</exception>
        /// <exception cref="T:System.ComponentModel.Win32Exception">The system could not generate a handle to the service. -or-A service with that name is already installed.</exception>
        /// <PermissionSet>
        ///   <IPermission class="System.Security.Permissions.FileIOPermission, mscorlib, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Unrestricted="true" />
        ///   <IPermission class="System.Security.Permissions.SecurityPermission, mscorlib, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Flags="UnmanagedCode" />
        ///   <IPermission class="System.Security.Permissions.UIPermission, mscorlib, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Unrestricted="true" />
        /// </PermissionSet>
        public override void Install(IDictionary stateSaver)
        {
            base.Context.LogMessage(Res.GetString("InstallingService", this.ServiceName));
            try
            {
                ServiceInstaller.CheckEnvironment();
                string servicesStartName = null;
                string password          = null;
                ServiceProcessInstaller serviceProcessInstaller = null;
                if (base.Parent is ServiceProcessInstaller)
                {
                    serviceProcessInstaller = (ServiceProcessInstaller)base.Parent;
                }
                else
                {
                    int num = 0;
                    while (num < base.Parent.Installers.Count)
                    {
                        if (!(base.Parent.Installers[num] is ServiceProcessInstaller))
                        {
                            num++;
                            continue;
                        }
                        serviceProcessInstaller = (ServiceProcessInstaller)base.Parent.Installers[num];
                        break;
                    }
                }
                if (serviceProcessInstaller == null)
                {
                    throw new InvalidOperationException(Res.GetString("NoInstaller"));
                }
                switch (serviceProcessInstaller.Account)
                {
                case ServiceAccount.LocalService:
                    servicesStartName = "NT AUTHORITY\\LocalService";
                    break;

                case ServiceAccount.NetworkService:
                    servicesStartName = "NT AUTHORITY\\NetworkService";
                    break;

                case ServiceAccount.User:
                    servicesStartName = serviceProcessInstaller.Username;
                    password          = serviceProcessInstaller.Password;
                    break;
                }
                string text = base.Context.Parameters["assemblypath"];
                if (string.IsNullOrEmpty(text))
                {
                    throw new InvalidOperationException(Res.GetString("FileName"));
                }
                if (text.IndexOf('"') == -1)
                {
                    text = "\"" + text + "\"";
                }
                if (!ServiceInstaller.ValidateServiceName(this.ServiceName))
                {
                    throw new InvalidOperationException(Res.GetString("ServiceName", this.ServiceName, 80.ToString(CultureInfo.CurrentCulture)));
                }
                if (this.DisplayName.Length > 255)
                {
                    throw new ArgumentException(Res.GetString("DisplayNameTooLong", this.DisplayName));
                }
                string dependencies = null;
                if (this.ServicesDependedOn.Length != 0)
                {
                    StringBuilder stringBuilder = new StringBuilder();
                    for (int i = 0; i < this.ServicesDependedOn.Length; i++)
                    {
                        string text2 = this.ServicesDependedOn[i];
                        try
                        {
                            text2 = new ServiceController(text2, ".").ServiceName;
                        }
                        catch
                        {
                        }
                        stringBuilder.Append(text2);
                        stringBuilder.Append('\0');
                    }
                    stringBuilder.Append('\0');
                    dependencies = stringBuilder.ToString();
                }
                IntPtr intPtr  = SafeNativeMethods.OpenSCManager(null, null, 983103);
                IntPtr intPtr2 = IntPtr.Zero;
                if (intPtr == IntPtr.Zero)
                {
                    throw new InvalidOperationException(Res.GetString("OpenSC", "."), new Win32Exception());
                }
                int serviceType = 16;
                int num2        = 0;
                for (int j = 0; j < base.Parent.Installers.Count; j++)
                {
                    if (base.Parent.Installers[j] is ServiceInstaller)
                    {
                        num2++;
                        if (num2 > 1)
                        {
                            break;
                        }
                    }
                }
                if (num2 > 1)
                {
                    serviceType = 32;
                }
                try
                {
                    intPtr2 = NativeMethods.CreateService(intPtr, this.ServiceName, this.DisplayName, 983551, serviceType, (int)this.StartType, 1, text, null, IntPtr.Zero, dependencies, servicesStartName, password);
                    if (intPtr2 == IntPtr.Zero)
                    {
                        throw new Win32Exception();
                    }
                    if (this.Description.Length != 0)
                    {
                        NativeMethods.SERVICE_DESCRIPTION sERVICE_DESCRIPTION = default(NativeMethods.SERVICE_DESCRIPTION);
                        sERVICE_DESCRIPTION.description = Marshal.StringToHGlobalUni(this.Description);
                        bool num3 = NativeMethods.ChangeServiceConfig2(intPtr2, 1u, ref sERVICE_DESCRIPTION);
                        Marshal.FreeHGlobal(sERVICE_DESCRIPTION.description);
                        if (!num3)
                        {
                            throw new Win32Exception();
                        }
                    }
                    if (Environment.OSVersion.Version.Major > 5 && this.StartType == ServiceStartMode.Automatic)
                    {
                        NativeMethods.SERVICE_DELAYED_AUTOSTART_INFO sERVICE_DELAYED_AUTOSTART_INFO = default(NativeMethods.SERVICE_DELAYED_AUTOSTART_INFO);
                        sERVICE_DELAYED_AUTOSTART_INFO.fDelayedAutostart = this.DelayedAutoStart;
                        if (!NativeMethods.ChangeServiceConfig2(intPtr2, 3u, ref sERVICE_DELAYED_AUTOSTART_INFO))
                        {
                            throw new Win32Exception();
                        }
                    }
                    stateSaver["installed"] = true;
                }
                finally
                {
                    if (intPtr2 != IntPtr.Zero)
                    {
                        SafeNativeMethods.CloseServiceHandle(intPtr2);
                    }
                    SafeNativeMethods.CloseServiceHandle(intPtr);
                }
                base.Context.LogMessage(Res.GetString("InstallOK", this.ServiceName));
            }
            finally
            {
                base.Install(stateSaver);
            }
        }
コード例 #3
0
        /// <include file='doc\ServiceInstaller.uex' path='docs/doc[@for="ServiceInstaller.Install"]/*' />
        /// <devdoc>
        ///    <para>Installs the service by writing service application
        ///       information to the registry. This method is meant to be used by installation
        ///       tools, which process the appropriate methods automatically.</para>
        /// </devdoc>
        public unsafe override void Install(IDictionary stateSaver)
        {
            Context.LogMessage(Res.GetString(Res.InstallingService, ServiceName));
            try
            {
                CheckEnvironment();
                string userName = null;
                string password = null;
                // find the ServiceProcessInstaller for our process. It's either the
                // parent or one of our peers in the parent's Installers collection.
                ServiceProcessInstaller processInstaller = null;
                if (Parent is ServiceProcessInstaller)
                {
                    processInstaller = (ServiceProcessInstaller)Parent;
                }
                else
                {
                    for (int i = 0; i < Parent.Installers.Count; i++)
                    {
                        if (Parent.Installers[i] is ServiceProcessInstaller)
                        {
                            processInstaller = (ServiceProcessInstaller)Parent.Installers[i];
                            break;
                        }
                    }
                }

                if (processInstaller == null)
                {
                    throw new InvalidOperationException(Res.GetString(Res.NoInstaller));
                }

                switch (processInstaller.Account)
                {
                case ServiceAccount.LocalService:
                    userName = LocalServiceName;
                    break;

                case ServiceAccount.NetworkService:
                    userName = NetworkServiceName;
                    break;

                case ServiceAccount.User:
                    userName = processInstaller.Username;
                    password = processInstaller.Password;
                    break;
                }

                // check all our parameters

                string moduleFileName = Context.Parameters["assemblypath"];
                if (String.IsNullOrEmpty(moduleFileName))
                {
                    throw new InvalidOperationException(Res.GetString(Res.FileName));
                }

                // Put quotas around module file name. Otherwise a service might fail to start if there is space in the path.
                // Note: Though CreateService accepts a binaryPath allowing
                // arguments for automatic services, in /assemblypath=foo,
                // foo is simply the path to the executable.
                // Therefore, it is best to quote if there are no quotes,
                // and best to not quote if there are quotes.
                if (moduleFileName.IndexOf('\"') == -1)
                {
                    moduleFileName = "\"" + moduleFileName + "\"";
                }

                //Check service name
                if (!ValidateServiceName(ServiceName))
                {
                    //Event Log cannot be used here, since the service doesn't exist yet.
                    throw new InvalidOperationException(Res.GetString(Res.ServiceName, ServiceName, ServiceBase.MaxNameLength.ToString(CultureInfo.CurrentCulture)));
                }

                // Check DisplayName length.
                if (DisplayName.Length > 255)
                {
                    // MSDN suggests that 256 is the max length, but in
                    // fact anything over 255 causes problems.
                    throw new ArgumentException(Res.GetString(Res.DisplayNameTooLong, DisplayName));
                }

                //Build servicesDependedOn string
                string servicesDependedOn = null;
                if (ServicesDependedOn.Length > 0)
                {
                    StringBuilder buff = new StringBuilder();
                    for (int i = 0; i < ServicesDependedOn.Length; ++i)
                    {
                        // we have to build a list of the services' short names. But the user
                        // might have used long names in the ServicesDependedOn property. Try
                        // to use ServiceController's logic to get the short name.
                        string tempServiceName = ServicesDependedOn[i];
                        try
                        {
                            ServiceController svc = new ServiceController(tempServiceName, ".");
                            tempServiceName = svc.ServiceName;
                        }
                        catch
                        {
                        }
                        //The servicesDependedOn need to be separated by a null
                        buff.Append(tempServiceName);
                        buff.Append('\0');
                    }
                    // an extra null at the end indicates end of list.
                    buff.Append('\0');

                    servicesDependedOn = buff.ToString();
                }

                // Open the service manager
                IntPtr serviceManagerHandle = SafeNativeMethods.OpenSCManager(null, null, NativeMethods.SC_MANAGER_ALL);
                IntPtr serviceHandle        = IntPtr.Zero;
                if (serviceManagerHandle == IntPtr.Zero)
                {
                    throw new InvalidOperationException(Res.GetString(Res.OpenSC, "."), new Win32Exception());
                }

                int serviceType = NativeMethods.SERVICE_TYPE_WIN32_OWN_PROCESS;
                // count the number of UserNTServiceInstallers. More than one means we set the SHARE_PROCESS flag.
                int serviceInstallerCount = 0;
                for (int i = 0; i < Parent.Installers.Count; i++)
                {
                    if (Parent.Installers[i] is ServiceInstaller)
                    {
                        serviceInstallerCount++;
                        if (serviceInstallerCount > 1)
                        {
                            break;
                        }
                    }
                }
                if (serviceInstallerCount > 1)
                {
                    serviceType = NativeMethods.SERVICE_TYPE_WIN32_SHARE_PROCESS;
                }

                try
                {
                    // Install the service
                    serviceHandle = NativeMethods.CreateService(serviceManagerHandle, ServiceName,
                                                                DisplayName, NativeMethods.ACCESS_TYPE_ALL, serviceType,
                                                                (int)StartType, NativeMethods.ERROR_CONTROL_NORMAL,
                                                                moduleFileName, null, IntPtr.Zero, servicesDependedOn, userName, password);

                    if (serviceHandle == IntPtr.Zero)
                    {
                        throw new Win32Exception();
                    }

                    // A local variable in an unsafe method is already fixed -- so we don't need a "fixed { }" blocks to protect
                    // across the p/invoke calls below.

                    if (Description.Length != 0)
                    {
                        NativeMethods.SERVICE_DESCRIPTION serviceDesc = new NativeMethods.SERVICE_DESCRIPTION();
                        serviceDesc.description = Marshal.StringToHGlobalUni(Description);
                        bool success = NativeMethods.ChangeServiceConfig2(serviceHandle, NativeMethods.SERVICE_CONFIG_DESCRIPTION, ref serviceDesc);
                        Marshal.FreeHGlobal(serviceDesc.description);
                        if (!success)
                        {
                            throw new Win32Exception();
                        }
                    }

                    if (Environment.OSVersion.Version.Major > 5)
                    {
                        if (StartType == ServiceStartMode.Automatic)
                        {
                            NativeMethods.SERVICE_DELAYED_AUTOSTART_INFO serviceDelayedInfo = new NativeMethods.SERVICE_DELAYED_AUTOSTART_INFO();
                            serviceDelayedInfo.fDelayedAutostart = DelayedAutoStart;
                            bool success = NativeMethods.ChangeServiceConfig2(serviceHandle, NativeMethods.SERVICE_CONFIG_DELAYED_AUTO_START_INFO, ref serviceDelayedInfo);
                            if (!success)
                            {
                                throw new Win32Exception();
                            }
                        }
                    }

                    stateSaver["installed"] = true;
                }
                finally
                {
                    if (serviceHandle != IntPtr.Zero)
                    {
                        SafeNativeMethods.CloseServiceHandle(serviceHandle);
                    }

                    SafeNativeMethods.CloseServiceHandle(serviceManagerHandle);
                }
                Context.LogMessage(Res.GetString(Res.InstallOK, ServiceName));
            }
            finally
            {
                base.Install(stateSaver);
            }
        }