AIT.Tools.VisualStudioTextTransform.DteHelper.CreateDteInstance C# (CSharp) Method

CreateDteInstance() public static method

public static CreateDteInstance ( ) : DTE2>.Tuple
return DTE2>.Tuple
        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;
                }
            }
        }

Usage Example

        /// <summary>
        /// /
        /// </summary>
        /// <param name="solutionFileName"></param>
        /// <param name="options"></param>
        /// <returns></returns>
        public static bool ProcessSolution(string solutionFileName, Options options)
        {
            if (string.IsNullOrEmpty(solutionFileName) || !File.Exists(solutionFileName))
            {
                throw new ArgumentException(
                          string.Format(CultureInfo.CurrentUICulture,
                                        Resources.Program_Main_the_file_path___0___is_either_invalid_or_doesn_t_exist_, solutionFileName));
            }

            solutionFileName = Path.GetFullPath(solutionFileName);
            Source.TraceEvent(TraceEventType.Information, 0, Resources.Program_Main_Creating_VS_instance___);
            using (new MessageFilter())
            {
                var result    = DteHelper.CreateDteInstance();
                var dte       = result.Item2;
                var processId = result.Item1;
                try
                {
                    Source.TraceEvent(TraceEventType.Information, 0, Resources.Program_Main_Opening__0_, solutionFileName);
                    dte.Solution.Open(solutionFileName);

                    Source.TraceEvent(TraceEventType.Verbose, 0, Resources.Program_Main_Finding_and_processing___tt_templates___);
                    var firstError =
                        FindTemplates(Path.GetDirectoryName(solutionFileName))
                        .Select(t => Tuple.Create(t, ProcessTemplate(dte, t, options)))
                        .FirstOrDefault(tuple => tuple.Item2.Count > 0);

                    if (firstError != null)
                    {
                        Source.TraceEvent(TraceEventType.Warning, 0, Resources.Program_Main_FAILED_to_process___0__,
                                          firstError.Item1);
                        foreach (var error in firstError.Item2)
                        {
                            Source.TraceEvent(TraceEventType.Error, 0, Resources.Program_Main_, error);
                        }
                        return(false);
                    }

                    Source.TraceEvent(TraceEventType.Information, 0, Resources.Program_Main_Everything_worked_);
                    return(true);
                }
                finally
                {
                    Process process = null;
                    if (processId > 0)
                    {
                        process = Process.GetProcessById(processId);
                    }
                    dte.Quit();

                    // Makes no sense to wait when the process already exited, or when we have no processId to kill.
                    int i = 0;
                    while (i < 10 && process != null && !process.HasExited)
                    {
                        Thread.Sleep(1000);
                        i++;
                    }
                    if (process != null && !process.HasExited)
                    {
                        process.Kill();
                    }
                }
            }
        }