/
githubmirror
/
roslyn
Обзор
Документация
Войти
/
githubmirror
/
roslyn
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
src/VisualStudio/IntegrationTest/Harness/XUnitShared/InProcess/InProcComponent.cs
99 строк
4 KB
David Barbet
Shorten file paths to prevent long path issues opening the slnx
10 дек 2025, 22:44
10 дек 2025, 22:44
7830fcf
Код
Авторство
О чём код?
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. namespace Xunit.InProcess { using System; using System.Threading; using System.Windows; using System.Windows.Threading; using Microsoft.VisualStudio.Shell.Interop; using Xunit.Harness; using DTE = EnvDTE.DTE; /// <summary> /// Base class for all components that run inside of the Visual Studio process. /// <list type="bullet"> /// <item>Every in-proc component should provide a public, static, parameterless "Create" method. /// This will be called to construct the component in the VS process.</item> /// <item>Public methods on in-proc components should be instance methods to ensure that they are /// marshalled properly and execute in the VS process. Static methods will execute in the process /// in which they are called.</item> /// </list> /// </summary> internal abstract class InProcComponent : MarshalByRefObject { protected InProcComponent() { } private static Dispatcher CurrentApplicationDispatcher => Application.Current.Dispatcher; protected static void BeginInvokeOnUIThread(Action action) #pragma warning disable VSTHRD001 // Avoid legacy thread switching APIs => CurrentApplicationDispatcher.BeginInvoke(action, DispatcherPriority.Background); #pragma warning restore VSTHRD001 // Avoid legacy thread switching APIs protected static void InvokeOnUIThread(Action action) { if (CurrentApplicationDispatcher.CheckAccess()) { // Invoke the action directly action(); } else { #pragma warning disable VSTHRD001 // Avoid legacy thread switching APIs CurrentApplicationDispatcher.Invoke(action, DispatcherPriority.Background); #pragma warning restore VSTHRD001 // Avoid legacy thread switching APIs } } protected static T InvokeOnUIThread<T>(Func<T> action) { if (CurrentApplicationDispatcher.CheckAccess()) { // Invoke the action directly return action(); } else { #pragma warning disable VSTHRD001 // Avoid legacy thread switching APIs return CurrentApplicationDispatcher.Invoke(action, DispatcherPriority.Background); #pragma warning restore VSTHRD001 // Avoid legacy thread switching APIs } } protected static TInterface GetGlobalService<TService, TInterface>() where TService : class where TInterface : class => InvokeOnUIThread(() => (TInterface)new OleServiceProvider(GetDTE()).GetService(typeof(TService))); protected static DTE GetDTE() => InvokeOnUIThread(() => (DTE)GlobalServiceProvider.ServiceProvider.GetService(typeof(SDTE))); protected static bool IsCommandAvailable(string commandName) => GetDTE().Commands.Item(commandName).IsAvailable; protected static void ExecuteCommand(string commandName, string args = "") => GetDTE().ExecuteCommand(commandName, args); /// <summary> /// Waiting for the application to 'idle' means that it is done pumping messages (including WM_PAINT). /// </summary> protected static void WaitForApplicationIdle() #pragma warning disable VSTHRD001 // Avoid legacy thread switching APIs => CurrentApplicationDispatcher.Invoke(() => { }, DispatcherPriority.ApplicationIdle); #pragma warning restore VSTHRD001 // Avoid legacy thread switching APIs protected static void WaitForSystemIdle() #pragma warning disable VSTHRD001 // Avoid legacy thread switching APIs => CurrentApplicationDispatcher.Invoke(() => { }, DispatcherPriority.SystemIdle); #pragma warning restore VSTHRD001 // Avoid legacy thread switching APIs // Ensure InProcComponents live forever public override object? InitializeLifetimeService() => null; } }