How do I debug Windows services in Visual Studio?

后端 未结 17 649
梦毁少年i
梦毁少年i 2020-11-28 03:56

Is it possible to debug the Windows services in Visual Studio?

I used code like

System.Diagnostics.Debugger.Break();

but it is givi

相关标签:
17条回答
  • 2020-11-28 04:13

    Try Visual Studio's very own post-build event command line.

    Try to add this in post-build:

    @echo off
    sc query "ServiceName" > nul
    if errorlevel 1060 goto install
    goto stop
    
    :delete
    echo delete
    sc delete "ServiceName" > nul
    echo %errorlevel%
    goto install
    
    :install
    echo install
    sc create "ServiceName" displayname= "Service Display Name" binpath= "$(TargetPath)" start= auto > nul
    echo %errorlevel%
    goto start
    
    :start
    echo start
    sc start "ServiceName" > nul
    echo %errorlevel%
    goto end
    
    :stop
    echo stop
    sc stop "ServiceName" > nul
    echo %errorlevel%
    goto delete
    
    :end
    

    If the build error with a message like Error 1 The command "@echo off sc query "ServiceName" > nul so on, Ctrl + C then Ctrl + V the error message into Notepad and look at the last sentence of the message.

    It could be saying exited with code x. Look for the code in some common error here and see how to resolve it.

    1072 -- Marked for deletion → Close all applications that maybe using the service including services.msc and Windows event log.
    1058 -- Can't be started because disabled or has no enabled associated devices → just delete it.
    1060 -- Doesn't exist → just delete it.
    1062 -- Has not been started → just delete it.
    1053 -- Didn't respond to start or control → see event log (if logged to event log). It may be the service itself throwing an exception.
    1056 -- Service is already running → stop the service, and then delete.
    

    More on error codes here.

    And if the build error with message like this,

    Error    11    Could not copy "obj\x86\Debug\ServiceName.exe" to "bin\Debug\ServiceName.exe". Exceeded retry count of 10. Failed.    ServiceName
    Error    12    Unable to copy file "obj\x86\Debug\ServiceName.exe" to "bin\Debug\ServiceName.exe". The process cannot access the file 'bin\Debug\ServiceName.exe' because it is being used by another process.    ServiceName
    

    open cmd, and then try to kill it first with taskkill /fi "services eq ServiceName" /f

    If all is well, F5 should be sufficient to debug it.

    0 讨论(0)
  • 2020-11-28 04:13

    Debug a Windows Service over http (tested with VS 2015 Update 3 and .Net FW 4.6)

    Firstly, you have to create a Console Project within your VS Solution(Add -> New Project -> Console Application).

    Within the new project, create a class "ConsoleHost" with that code:

    class ConsoleHost : IDisposable
    {
        public static Uri BaseAddress = new Uri(http://localhost:8161/MyService/mex);
        private ServiceHost host;
    
        public void Start(Uri baseAddress)
        {
            if (host != null) return;
    
            host = new ServiceHost(typeof(MyService), baseAddress ?? BaseAddress);
    
            //binding
            var binding = new BasicHttpBinding()
            {
                Name = "MyService",
                MessageEncoding = WSMessageEncoding.Text,
                TextEncoding = Encoding.UTF8,
                MaxBufferPoolSize = 2147483647,
                MaxBufferSize = 2147483647,
                MaxReceivedMessageSize = 2147483647
            };
    
            host.Description.Endpoints.Clear();
            host.AddServiceEndpoint(typeof(IMyService), binding, baseAddress ?? BaseAddress);
    
            // Enable metadata publishing.
            var smb = new ServiceMetadataBehavior
            {
                HttpGetEnabled = true,
                MetadataExporter = { PolicyVersion = PolicyVersion.Policy15 },
            };
    
            host.Description.Behaviors.Add(smb);
    
            var defaultBehaviour = host.Description.Behaviors.OfType<ServiceDebugBehavior>().FirstOrDefault();
            if (defaultBehaviour != null)
            {
                defaultBehaviour.IncludeExceptionDetailInFaults = true;
            }
    
            host.Open();
        }
    
        public void Stop()
        {
            if (host == null)
                return;
    
            host.Close();
            host = null;
        }
    
        public void Dispose()
        {
            this.Stop();
        }
    }
    

    And this is the code for the Program.cs class:

    public static class Program
    {
        [STAThread]
        public static void Main(string[] args)
        {
            var baseAddress = new Uri(http://localhost:8161/MyService);
            var host = new ConsoleHost();
            host.Start(null);
            Console.WriteLine("The service is ready at {0}", baseAddress);
            Console.WriteLine("Press <Enter> to stop the service.");
            Console.ReadLine();
            host.Stop();
        }
    }
    

    Configurations such as connectionstrings should be copied in the App.config file of the Console project.

    To sturt up the console, righ-click on Console project and click Debug -> Start new instance.

    0 讨论(0)
  • 2020-11-28 04:14

    Use the following code in service OnStart method:

    System.Diagnostics.Debugger.Launch();
    

    Choose the Visual Studio option from the pop up message.

    Note: To use it in only Debug mode, a #if DEBUG compiler directive can be used, as follows. This will prevent accidental or debugging in release mode on a production server.

    #if DEBUG
        System.Diagnostics.Debugger.Launch();
    #endif
    
    0 讨论(0)
  • 2020-11-28 04:17

    You can make a console application. I use this main function:

        static void Main(string[] args)
        {
            ImportFileService ws = new ImportFileService();
            ws.OnStart(args);
            while (true)
            {
                ConsoleKeyInfo key = System.Console.ReadKey();
                if (key.Key == ConsoleKey.Escape)
                    break;
            }
            ws.OnStop();
        }
    

    My ImportFileService class is exactly the same as in my Windows service's application, except the inheritant (ServiceBase).

    0 讨论(0)
  • 2020-11-28 04:19

    Just add a contructor to your service class (if you don't have it already). Below, you can check and example for visual basic .net.

    Public Sub New()
       OnStart(Nothing) 
    End Sub
    

    After, that, right-click on project and select "Debug -> Start a new instance".

    0 讨论(0)
  • 2020-11-28 04:20

    I'm using the /Console parameter in the Visual Studio project DebugStart OptionsCommand line arguments:

    public static class Program
    {
        [STAThread]
        public static void Main(string[] args)
        {
             var runMode = args.Contains(@"/Console")
                 ? WindowsService.RunMode.Console
                 : WindowsService.RunMode.WindowsService;
             new WinodwsService().Run(runMode);
        }
    }
    
    
    public class WindowsService : ServiceBase
    {
        public enum RunMode
        {
            Console,
            WindowsService
        }
    
        public void Run(RunMode runMode)
        {
            if (runMode.Equals(RunMode.Console))
            {
                this.StartService();
                Console.WriteLine("Press <ENTER> to stop service...");
                Console.ReadLine();
    
                this.StopService();
                Console.WriteLine("Press <ENTER> to exit.");
                Console.ReadLine();
            }
            else if (runMode.Equals(RunMode.WindowsService))
            {
                ServiceBase.Run(new[] { this });
            }
        }
    
        protected override void OnStart(string[] args)
        {
            StartService(args);
        }
    
        protected override void OnStop()
        {
            StopService();
        }
    
        /// <summary>
        /// Logic to Start Service
        /// Public accessibility for running as a console application in Visual Studio debugging experience
        /// </summary>
        public virtual void StartService(params string[] args){ ... }
    
        /// <summary>
        /// Logic to Stop Service
        /// Public accessibility for running as a console application in Visual Studio debugging experience
        /// </summary>
        public virtual void StopService() {....}
    }
    
    0 讨论(0)
提交回复
热议问题