/// <summary>
/// Start experimental instance of Visual Studio. This will be killed on cleanup, except if a debugger is attached (in which case it can reuse the existing instance).
/// </summary>
private static (DTE, Process, bool) InitDTE()
{
bool killVisualStudioProcessDuringTearDown;
var visualStudioPath = VSLocator.VisualStudioPath;
Process process;
// First, we try to check if an existing instance was launched
var searcher = new ManagementObjectSearcher($"select CommandLine,ProcessId from Win32_Process where ExecutablePath='{visualStudioPath.Replace(@"\", @"\\")}' and CommandLine like '% /RootSuffix Exp'");
var retObjectCollection = searcher.Get();
var result = retObjectCollection.Cast <ManagementObject>().FirstOrDefault();
if (result != null)
{
var processId = (uint)result["ProcessId"];
process = Process.GetProcessById((int)processId);
killVisualStudioProcessDuringTearDown = false;
}
else
{
var psi = new ProcessStartInfo
{
FileName = visualStudioPath,
WorkingDirectory = Path.GetDirectoryName(visualStudioPath),
Arguments = StartArguments,
UseShellExecute = false,
};
// Override Xenko dir with path relative to test directory
psi.EnvironmentVariables["XenkoDir"] = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"..\..\..\..");
process = Process.Start(psi);
if (process == null)
{
throw new InvalidOperationException("Could not start Visual Studio instance");
}
// Since we are the one starting it, let's close it when we are done
// (except if a debugger is attached, we assume developer want to iterate several time on it and will exit Visual Studio himself)
killVisualStudioProcessDuringTearDown = !Debugger.IsAttached;
}
// Wait for 60 sec
for (int i = 0; i < 60; ++i)
{
if (process.HasExited)
{
throw new InvalidOperationException($"Visual Studio process {process.Id} exited before we could connect to it");
}
var matchingDte = VisualStudioDTE.GetDTEByProcess(process.Id);
if (matchingDte != null)
{
return(matchingDte, process, killVisualStudioProcessDuringTearDown);
}
Thread.Sleep(1000);
}
throw new InvalidOperationException($"Could not find the Visual Studio DTE for process {process.Id}, or it didn't start in time");
}