public static Tuple<int, DTE2> CreateDteInstance()
{
if (!Settings.Default.SelfHostVisualStudio)
{
Source.TraceEvent(TraceEventType.Warning, 0, "Self-hosting is disabled");
return CreateDteInstanceWithActivator();
}
// We Create our own instance for customized logging + killing afterwards
var pf = Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles);
var pfx64 = Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86);
var vs2013Relative = Path.Combine("Microsoft Visual Studio 12.0", "Common7", "IDE", "devenv.exe");
var testPaths = new[]
{
Path.Combine(pf, vs2013Relative),
Path.Combine(pfx64, vs2013Relative)
};
var devenvExe = testPaths.FirstOrDefault(File.Exists);
if (string.IsNullOrEmpty(devenvExe))
{
Source.TraceEvent(TraceEventType.Error, 0, "Could not find devenv.exe, falling back to COM.");
return CreateDteInstanceWithActivator();
}
using (var start =
Process.Start(
devenvExe,
string.Format(CultureInfo.InvariantCulture, "-Embedding /log \"{0}\"",
Path.GetFullPath(Settings.Default.VisualStudioLogfile))))
{
if (start == null)
{
Source.TraceEvent(TraceEventType.Error, 0, "Could not start devenv.exe, falling back to COM.");
return CreateDteInstanceWithActivator();
}
try
{
DTE2 dte = null;
var timeout = TimeSpan.FromMinutes(5);
var currentSpan = TimeSpan.Zero;
var waitTime = TimeSpan.FromSeconds(10);
while (dte == null && currentSpan < timeout && !start.HasExited)
{
Thread.Sleep(waitTime);
Source.TraceInformation("Trying to get DTE instance from process...");
dte = GetById(start.Id);
currentSpan += waitTime;
}
if (dte == null)
{
if (!start.HasExited)
{
start.Kill();
}
Source.TraceEvent(TraceEventType.Error, 1, "Could not get DTE instance from process!");
return CreateDteInstanceWithActivator();
}
return Tuple.Create(start.Id, dte);
}
catch (Exception e)
{
Source.TraceEvent(TraceEventType.Verbose, 0, "Killing devenv.exe because of error while fetching dte instance from process: {0}",
e);
if (!start.HasExited)
{
start.Kill();
}
throw;
}
}
}