IntegrationTestServiceCommands.cs 4.8 KB
Newer Older
1 2 3 4
// Copyright (c) Microsoft.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.

using System;
using System.ComponentModel.Design;
5
using System.Diagnostics;
6 7 8 9
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Ipc;
using System.Runtime.Serialization.Formatters;
10
using Microsoft.VisualStudio.IntegrationTest.Utilities;
11 12
using Microsoft.VisualStudio.Shell;

13
namespace Microsoft.VisualStudio.IntegrationTest.Setup
14 15 16
{
    internal sealed class IntegrationTestServiceCommands : IDisposable
    {
17 18
        #region VSCT Identifiers
        public const int menuidIntegrationTestService = 0x5001;
19

20 21
        public const int grpidTestWindowRunTopLevelMenu = 0x0110;
        public const int grpidIntegrationTestService = 0x5101;
22

23 24 25 26 27 28
        public const int cmdidStartIntegrationTestService = 0x5201;
        public const int cmdidStopIntegrationTestService = 0x5204;

        public static readonly Guid guidTestWindowCmdSet = new Guid("1E198C22-5980-4E7E-92F3-F73168D1FB63");
        #endregion

D
dotnet-bot 已提交
29 30
        private static readonly BinaryServerFormatterSinkProvider DefaultSinkProvider = new BinaryServerFormatterSinkProvider()
        {
31 32 33 34
            TypeFilterLevel = TypeFilterLevel.Full
        };

        private readonly Package _package;
35 36 37

        private readonly MenuCommand _startMenuCmd;
        private readonly MenuCommand _stopMenuCmd;
38 39 40 41 42 43 44

        private IntegrationService _service;
        private IpcServerChannel _serviceChannel;
        private ObjRef _marshalledService;

        private IntegrationTestServiceCommands(Package package)
        {
45
            _package = package ?? throw new ArgumentNullException(nameof(package));
46 47


J
Jonathon Marolf 已提交
48
            if (ServiceProvider.GetService(typeof(IMenuCommandService)) is OleMenuCommandService menuCommandService)
49
            {
50
                var startMenuCmdId = new CommandID(guidTestWindowCmdSet, cmdidStartIntegrationTestService);
J
Jonathon Marolf 已提交
51 52
                _startMenuCmd = new MenuCommand(StartServiceCallback, startMenuCmdId)
                {
53 54 55
                    Enabled = true,
                    Visible = true
                };
56
                menuCommandService.AddCommand(_startMenuCmd);
57

58
                var stopMenuCmdId = new CommandID(guidTestWindowCmdSet, cmdidStopIntegrationTestService);
J
Jonathon Marolf 已提交
59 60
                _stopMenuCmd = new MenuCommand(StopServiceCallback, stopMenuCmdId)
                {
61 62 63
                    Enabled = false,
                    Visible = false
                };
64
                menuCommandService.AddCommand(_stopMenuCmd);
65 66 67 68 69
            }
        }

        public static IntegrationTestServiceCommands Instance { get; private set; }

70
        private IServiceProvider ServiceProvider => _package;
71 72 73 74 75 76

        public static void Initialize(Package package)
        {
            Instance = new IntegrationTestServiceCommands(package);
        }

77 78
        public void Dispose()
            => StopServiceCallback(this, EventArgs.Empty);
79

D
Dustin Campbell 已提交
80 81 82
        /// <summary>
        /// Starts the IPC server for the Integration Test service.
        /// </summary>
83 84
        private void StartServiceCallback(object sender, EventArgs e)
        {
85
            if (_startMenuCmd.Enabled)
86
            {
87 88
                IntegrationTestTraceListener.Install();

89
                _service = new IntegrationService();
D
Dustin Campbell 已提交
90 91

                _serviceChannel = new IpcServerChannel(
92
                    name: $"Microsoft.VisualStudio.IntegrationTest.ServiceChannel_{Process.GetCurrentProcess().Id}",
D
Dustin Campbell 已提交
93
                    portName: _service.PortName,
94 95
                    sinkProvider: DefaultSinkProvider
                );
96 97 98 99 100 101

                var serviceType = typeof(IntegrationService);
                _marshalledService = RemotingServices.Marshal(_service, serviceType.FullName, serviceType);

                _serviceChannel.StartListening(null);

102
                SwapAvailableCommands(_startMenuCmd, _stopMenuCmd);
103 104 105
            }
        }

106
        /// <summary>Stops the IPC server for the Integration Test service.</summary>
107 108
        private void StopServiceCallback(object sender, EventArgs e)
        {
109
            if (_stopMenuCmd.Enabled)
110
            {
111 112 113 114 115
                if (_serviceChannel != null)
                {
                    _serviceChannel.StopListening(null);
                    _serviceChannel = null;
                }
116 117 118 119

                _marshalledService = null;
                _service = null;

120
                SwapAvailableCommands(_stopMenuCmd, _startMenuCmd);
121 122 123 124 125 126 127 128 129 130 131 132 133
            }
        }

        private void SwapAvailableCommands(MenuCommand commandToDisable, MenuCommand commandToEnable)
        {
            commandToDisable.Enabled = false;
            commandToDisable.Visible = false;

            commandToEnable.Enabled = true;
            commandToEnable.Visible = true;
        }
    }
}