/
githubmirror
/
roslyn
Обзор
Документация
Войти
/
githubmirror
/
roslyn
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
src/VisualStudio/IntegrationTest/Harness/IntegrationTestServiceShared/IntegrationService.cs
95 строк
4 KB
Jan Jones
Allow running DartLab as VS test gate (#83690)
01 июн 2026, 18:52
Не верифицирован
01 июн 2026, 18:52
9450aa6
Код
Авторство
О чём код?
// 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 Microsoft.VisualStudio.IntegrationTestService { using System; using System.Collections.Concurrent; using System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime.Remoting; using Microsoft.VisualStudio.IntegrationTest; /// <summary> /// Provides a means of executing code in the Visual Studio host process. /// </summary> /// <remarks> /// This object exists in the Visual Studio host and is marshaled across the process boundary. /// </remarks> public class IntegrationService : MarshalByRefObject { private readonly ConcurrentDictionary<string, ObjRef> _marshaledObjects = new ConcurrentDictionary<string, ObjRef>(); public IntegrationService() { PortName = GetPortName(Process.GetCurrentProcess().Id); BaseUri = "ipc://" + PortName; } public string PortName { get; } /// <summary> /// Gets the base Uri of the service. This resolves to a string such as <c>ipc://IntegrationService_{HostProcessId}"</c>. /// </summary> public string BaseUri { get; } private static string GetPortName(int hostProcessId) { // Make the channel name well-known by using a static base and appending the process ID of the host return $"{nameof(IntegrationService)}_{{{hostProcessId}}}"; } public static IntegrationService GetInstanceFromHostProcess(Process hostProcess) { if (hostProcess is null) { throw new ArgumentNullException(nameof(hostProcess)); } var uri = $"ipc://{GetPortName(hostProcess.Id)}/{typeof(IntegrationService).FullName}"; return (IntegrationService)Activator.GetObject(typeof(IntegrationService), uri); } public string? Execute(string assemblyFilePath, string typeFullName, string methodName) { IntegrationTestAssemblyResolver.AddCodeBaseDirectory(Path.GetDirectoryName(assemblyFilePath)); var assembly = IntegrationTestAssemblyResolver.LoadAssemblyFromPath(assemblyFilePath); var type = assembly.GetType(typeFullName); var methodInfo = type.GetMethod(methodName, BindingFlags.Public | BindingFlags.Static); var result = methodInfo.Invoke(null, null); if (methodInfo.ReturnType == typeof(void)) { return null; } // Create a unique URL for each object returned, so that we can communicate with each object individually var resultType = result.GetType(); var marshallableResult = (MarshalByRefObject)result; var objectUri = $"{resultType.FullName}_{Guid.NewGuid()}"; var marshalledObject = RemotingServices.Marshal(marshallableResult, objectUri, resultType); if (!_marshaledObjects.TryAdd(objectUri, marshalledObject)) { throw new InvalidOperationException($"An object with the specified URI has already been marshaled. (URI: {objectUri})"); } return objectUri; } // Ensure in-process components live forever public override object? InitializeLifetimeService() { return null; } } }