How to enable the Net.Tcp Port Sharing Service software package?

I would like to programmatically enable and start the Net.Tcp port exchange service in C #. I can easily start the service using the ServiceController class. However, how do I enable a service that is disabled by default?

I found one recommendation online to set the following registry key 2 as follows, which supposedly sets the service startup type to “Automatic”:

string path = "SYSTEM\\CurrentControlSet\\Services\\" + serviceName;
using (RegistryKey key = Registry.LocalMachine.OpenSubKey(path, true)) {
    key.SetValue("Start", 2);
}

I tried this, and although it seems to have changed the startup type to “Automatic”, it should be bigger since the service will not start (programmatically or manually). I had to reset to run the type manually through services.msc to reset so that the service could be turned on and restarted.

Has anyone solved this?

+3
source share
2 answers

There are several ways to do this, depending on how clean the solution is. Here are a few options. Please note that all these decisions require administrative rights and must be carried out in an elevated process.

Use command line via C #

This will fire at sc.exeand change the type of service start using command line arguments. This is similar to the solution you mentioned above, except that you do not need to hack the registry.

namespace Sample
{
    using System;
    using System.Diagnostics;
    using System.Globalization;

    internal class ServiceSample
    {
        private static bool ChangeStartupType(string serviceName, string startupType)
        {
            string arguments = string.Format(
                CultureInfo.InvariantCulture,
                "config {0} start= {1}",
                serviceName,
                startupType);
            using (Process sc = Process.Start("sc.exe", arguments))
            {
                sc.WaitForExit();
                return sc.ExitCode == 0;
            }
        }

        private static void Main()
        {
            ServiceSample.ChangeStartupType("NetTcpPortSharing", "auto");
        }
    }
}

Use WMI

This requires an assembly reference for System.Management.dll. Here we will use the WMI functionality ChangeStartModefor the service.

namespace Sample
{
    using System;
    using System.Globalization;
    using System.Management;

    internal class ServiceSample
    {
        private static bool ChangeStartupType(string serviceName, string startupType)
        {
            const string MethodName = "ChangeStartMode";
            ManagementPath path = new ManagementPath();
            path.Server = ".";
            path.NamespacePath = @"root\CIMV2";
            path.RelativePath = string.Format(
                CultureInfo.InvariantCulture,
                "Win32_Service.Name='{0}'",
                serviceName);
            using (ManagementObject serviceObject = new ManagementObject(path))
            {
                ManagementBaseObject inputParameters = serviceObject.GetMethodParameters(MethodName);
                inputParameters["startmode"] = startupType;
                ManagementBaseObject outputParameters = serviceObject.InvokeMethod(MethodName, inputParameters, null);
                return (uint)outputParameters.Properties["ReturnValue"].Value == 0;
            }
        }

        private static void Main()
        {
            ServiceSample.ChangeStartupType("NetTcpPortSharing", "Automatic");
        }
    }
}

P/Invoke API Win32

"" , . ChangeServiceConfig .NET. OpenService OpenSCManager ( CloseServiceHandle, !).

. . . SafeHandle .

namespace Sample
{
    using System;
    using System.ComponentModel;
    using System.Runtime.InteropServices;

    internal class ServiceSample
    {
        private const uint SC_MANAGER_CONNECT = 0x1;
        private const uint SERVICE_CHANGE_CONFIG = 0x2;
        private const uint STANDARD_RIGHTS_WRITE = 0x20000;

        private const uint SERVICE_NO_CHANGE = 0xFFFFFFFF;

        private const uint SERVICE_AUTO_START = 0x2;
        private const uint SERVICE_DEMAND_START = 0x3;
        private const uint SERVICE_DISABLED = 0x4;

        [DllImport("advapi32.dll", SetLastError = true)]
        private static extern IntPtr OpenSCManager(string lpMachineName, string lpDatabaseName, uint dwDesiredAccess);

        [DllImport("advapi32.dll", SetLastError = true)]
        private static extern IntPtr OpenService(IntPtr hSCManager, string lpServiceName, uint dwDesiredAccess);

        [DllImport("advapi32.dll", SetLastError = true)]
        private static extern bool ChangeServiceConfig(IntPtr hService, uint dwServiceType, uint dwStartType, uint dwErrorControl, string lpBinaryPathName, string lpLoadOrderGroup, IntPtr lpdwTagId, string lpDependencies, string lpServiceStartName, string lpPassword, string lpDisplayName);

        [DllImport("advapi32.dll", SetLastError = true)]
        private static extern bool CloseServiceHandle(IntPtr hSCObject);

        private static bool ChangeStartupType(string serviceName, uint startType)
        {
            IntPtr scManager = ServiceSample.OpenSCManager(null, null, ServiceSample.SC_MANAGER_CONNECT);
            IntPtr service = ServiceSample.OpenService(scManager, serviceName, ServiceSample.SERVICE_CHANGE_CONFIG | ServiceSample.STANDARD_RIGHTS_WRITE);
            bool succeeded = ServiceSample.ChangeServiceConfig(service, ServiceSample.SERVICE_NO_CHANGE, startType, ServiceSample.SERVICE_NO_CHANGE, null, null, IntPtr.Zero, null, null, null, null);
            ServiceSample.CloseServiceHandle(service);
            ServiceSample.CloseServiceHandle(scManager);

            return succeeded;
        }

        private static void Main()
        {
            ServiceSample.ChangeStartupType("NetTcpPortSharing", ServiceSample.SERVICE_AUTO_START);
        }
    }
}
+11

ServiceController

System.ServiceProcess.ServiceController netTcpPortSharingService = new System.ServiceProcess.ServiceController("NetTcpPortSharing");

if (netTcpPortSharingService != null)
            {
                if(netTcpPortSharingService.Status!=ServiceControllerStatus.Running && netTcpPortSharingService.Status!=ServiceControllerStatus.StartPending)
                {
                    netTcpPortSharingService.Start();
                }
            }
0

Source: https://habr.com/ru/post/1730822/


All Articles