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.
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
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;
}
}
#endif2. 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