예제 #1
0
        public void FromCommandLineArgsRaceCondition()
        {
            // https://pytools.codeplex.com/workitem/1429

            var mre   = new ManualResetEvent(false);
            var tasks = new Task <bool> [100];

            try {
                for (int i = 0; i < tasks.Length; i += 1)
                {
                    tasks[i] = Task.Run(() => {
                        mre.WaitOne();
                        using (var arg = VisualStudioApp.FromProcessId(123)) {
                            return(arg is VisualStudioApp);
                        }
                    });
                }
                mre.Set();
                Assert.IsTrue(Task.WaitAll(tasks, TimeSpan.FromSeconds(30.0)));
                Assert.IsTrue(tasks.All(t => t.Result));
            } finally {
                mre.Dispose();
                Task.WaitAll(tasks, TimeSpan.FromSeconds(30.0));
            }
        }
예제 #2
0
        private static void AttachIfDebugging(Process targetVs)
        {
            if (!Debugger.IsAttached)
            {
                return;
            }

            // We are debugging tests, so attach the debugger to VS
            var selfId = Process.GetCurrentProcess().Id;

            foreach (var p in Process.GetProcessesByName("devenv"))
            {
                if (p.Id == targetVs.Id)
                {
                    continue;
                }

                using (VisualStudioApp vs = VisualStudioApp.FromProcessId(p.Id))
                {
                    EnvDTE.DTE dte;
                    try
                    {
                        dte = vs.GetDTE();
                    }
                    catch (InvalidOperationException)
                    {
                        // DTE is not available, which means VS has not been running
                        continue;
                    }

                    if (dte.Debugger.CurrentMode == EnvDTE.dbgDebugMode.dbgDesignMode)
                    {
                        // Not the correct VS
                        continue;
                    }

                    foreach (EnvDTE.Process dp in dte.Debugger.DebuggedProcesses)
                    {
                        if (dp.ProcessID == selfId)
                        {
                            // This is the correct VS, so attach and return.

                            vs.AttachToProcess(targetVs, null);
                            return;
                        }
                    }
                }
            }
        }
예제 #3
0
        public void StartOrRestart(
            string devenvExe,
            string devenvArguments,
            string testDataRoot,
            string tempRoot
            )
        {
            lock (_lock)
            {
                var settings = $"{devenvExe ?? ""};{devenvArguments ?? ""};{testDataRoot ?? ""};{tempRoot ?? ""}";
                if (_vs != null && _app != null)
                {
                    if (_currentSettings == settings)
                    {
                        return;
                    }
                    Console.WriteLine("Restarting VS because settings have changed");
                }
                _currentSettings = settings;
                CloseCurrentInstance();

                var psi = new ProcessStartInfo
                {
                    FileName               = devenvExe,
                    Arguments              = devenvArguments,
                    ErrorDialog            = false,
                    UseShellExecute        = false,
                    RedirectStandardOutput = true,
                    RedirectStandardError  = true
                };
                psi.Environment["_PTVS_UI_TEST"] = "1";
                if (!string.IsNullOrEmpty(testDataRoot))
                {
                    psi.Environment["_TESTDATA_ROOT_PATH"] = testDataRoot;
                }
                if (!string.IsNullOrEmpty(tempRoot))
                {
                    psi.Environment["_TESTDATA_TEMP_PATH"] = tempRoot;
                }

                _vs = Process.Start(psi);
                if (!NativeMethods.AssignProcessToJobObject(_jobObject, _vs.Handle))
                {
                    try
                    {
                        _vs.Kill();
                    }
                    catch (Exception)
                    {
                    }
                    _vs.Dispose();
                    throw new InvalidOperationException("Failed to add VS to our job object");
                }

                // Forward console output to our own output, which will
                // be captured by the test runner.
                _vs.OutputDataReceived += (s, e) => { if (e.Data != null)
                                                      {
                                                          Console.WriteLine(e.Data);
                                                      }
                };
                _vs.ErrorDataReceived += (s, e) => { if (e.Data != null)
                                                     {
                                                         Console.Error.WriteLine(e.Data);
                                                     }
                };
                _vs.BeginOutputReadLine();
                _vs.BeginErrorReadLine();

                // Always allow at least five seconds to start
                Thread.Sleep(5000);
                if (_vs.HasExited)
                {
                    throw new InvalidOperationException("Failed to start VS");
                }
                _app = VisualStudioApp.FromProcessId(_vs.Id);

                var        stopAt = DateTime.Now.AddSeconds(60);
                EnvDTE.DTE dte    = null;
                while (DateTime.Now < stopAt && dte == null)
                {
                    try
                    {
                        dte = _app.GetDTE();
                    }
                    catch (InvalidOperationException)
                    {
                        Thread.Sleep(1000);
                    }
                }
                if (dte == null)
                {
                    throw new InvalidOperationException("Failed to start VS");
                }

                AttachIfDebugging(_vs);
            }
        }