Thursday, 30 June 2016

Macro for connecting Visual Studio to windows service for debugging

Got this through today from my old colleague Kevin McConaghy,…
 
1.  Hack for service OnStart event, essentially to stall the service for long enough for the VS Extension to connect after starting it, only in debug mode and only if you send a special argument.
 
        protected override void OnStart(string[] args)
        {
#if DEBUG
            // If the "WaitForDebugger" argument is passed, wait for 15 seconds for a debugger to become attached.
            if (args.OfType<string>().Contains("WaitForDebugger"))
            {
                for (var i = 1; i <= 15; i++)
                {
                    if (Debugger.IsAttached)
                    {
                        break;
                    }
                    Thread.Sleep(1000);
                }
                // If no debugger is attached, abort attempt to start service.
                if (!Debugger.IsAttached)
                {
                    Stop();
                    return;
                }
            }
#endif
2. The vCmd script, this automates the starting of the service if it is not started, and then the connection of the debugger to the process.
using EnvDTE;
using EnvDTE80;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Management;
using System.ServiceProcess;
public class C : VisualCommanderExt.ICommand
{
    public void Run(EnvDTE80.DTE2 DTE, Microsoft.VisualStudio.Shell.Package package)
    {
        var serviceName = "MessagingService";
        using(var serviceController = new ServiceController(serviceName))
        using(var serviceManagement = new ManagementObject("Win32_Service.Name='"+serviceName+"'"))
        {
            // Start service with "WaitForDebugger" parameter, if the service is stopped.
            if (serviceController.Status == ServiceControllerStatus.Stopped)
            {
                serviceController.Start(new []{"WaitForDebugger"});
            }
            // Attach debugger to process.
            var servicePath = serviceManagement.Properties["PathName"].Value.ToString().Trim('\"');
            try
            {
                var serviceProcess = DTE.Debugger.LocalProcesses.OfType<Process>().Single(x => x.Name == servicePath);
                serviceProcess.Attach();
                return;
            }
            catch(Exception ex)
            {
                System.Windows.MessageBox.Show(string.Format("Could not find process: {0}, {1}.", servicePath, ex.Message));
            }
        }
    }
}
3. The script requires the following references, added via the button.
System.Core
System.Linq
System.ServiceProcess
System.Management





2 comments:

  1. Hi, Great.. Tutorial is just awesome..It is really helpful for a newbie like me.. I am a regular follower of your blog. Really very informative post you shared here. Kindly keep blogging. If anyone wants to become a .Net developer learn from Dot Net Training in Chennai. or learn thru Dot Net Training in Chennai. Nowadays Dot Net has tons of job opportunities on various vertical industry.
    or Javascript Training in Chennai. Nowadays JavaScript has tons of job opportunities on various vertical industry.

    ReplyDelete

Thames water collapsed drain cover

15/10/2018 After fixing our sewage drain cover, there appears to be a mini sinkhole occurring around our Thames Water meter cover. We’re w...