Ejemplo n.º 1
0
        protected override string GetDefaultPipeName()
        {
            var clientDirectory = AppDomain.CurrentDomain.BaseDirectory;

            return(BuildServerConnection.GetPipeNameForPathOpt(clientDirectory));
        }
 private Task <NamedPipeClientStream?> ConnectAsync(CancellationToken cancellationToken = default) => BuildServerConnection.TryConnectToServerAsync(
     _host.PipeName,
     timeoutMs: Timeout.Infinite,
     cancellationToken);
Ejemplo n.º 3
0
 protected override async Task <Stream> ConnectForShutdownAsync(string pipeName, int timeout)
 {
     return(await BuildServerConnection.TryConnectToServerAsync(pipeName, timeout, cancellationToken : default).ConfigureAwait(false));
 }
        protected override bool?WasServerRunning(string pipeName)
        {
            string mutexName = BuildServerConnection.GetServerMutexName(pipeName);

            return(BuildServerConnection.WasServerMutexOpen(mutexName));
        }
Ejemplo n.º 5
0
        protected override int ExecuteTool(string pathToTool, string responseFileCommands, string commandLineCommands)
        {
            if (ProvideCommandLineArgs)
            {
                CommandLineArgs = GetArguments(commandLineCommands, responseFileCommands)
                                  .Select(arg => new TaskItem(arg)).ToArray();
            }

            if (SkipCompilerExecution)
            {
                return(0);
            }

            try
            {
                var    workingDir = CurrentDirectoryToUse();
                string?tempDir    = BuildServerConnection.GetTempPath(workingDir);

                if (!UseSharedCompilation ||
                    HasToolBeenOverridden ||
                    !BuildServerConnection.IsCompilerServerSupported)
                {
                    return(base.ExecuteTool(pathToTool, responseFileCommands, commandLineCommands));
                }

                using (_sharedCompileCts = new CancellationTokenSource())
                {
                    CompilerServerLogger.Log($"CommandLine = '{commandLineCommands}'");
                    CompilerServerLogger.Log($"BuildResponseFile = '{responseFileCommands}'");

                    var clientDir = Path.GetDirectoryName(PathToManagedTool);
                    if (clientDir is null || tempDir is null)
                    {
                        return(base.ExecuteTool(pathToTool, responseFileCommands, commandLineCommands));
                    }

                    // Note: we can't change the "tool path" printed to the console when we run
                    // the Csc/Vbc task since MSBuild logs it for us before we get here. Instead,
                    // we'll just print our own message that contains the real client location
                    Log.LogMessage(ErrorString.UsingSharedCompilation, clientDir);

                    var buildPaths = new BuildPathsAlt(
                        clientDir: clientDir,
                        // MSBuild doesn't need the .NET SDK directory
                        sdkDir: null,
                        workingDir: workingDir,
                        tempDir: tempDir);

                    // Note: using ToolArguments here (the property) since
                    // commandLineCommands (the parameter) may have been mucked with
                    // (to support using the dotnet cli)
                    var responseTask = BuildServerConnection.RunServerCompilationAsync(
                        Language,
                        RoslynString.IsNullOrEmpty(SharedCompilationId) ? null : SharedCompilationId,
                        GetArguments(ToolArguments, responseFileCommands).ToList(),
                        buildPaths,
                        keepAlive: null,
                        libEnvVariable: LibDirectoryToUse(),
                        cancellationToken: _sharedCompileCts.Token);

                    responseTask.Wait(_sharedCompileCts.Token);

                    var response = responseTask.Result;
                    if (response != null)
                    {
                        ExitCode = HandleResponse(response, pathToTool, responseFileCommands, commandLineCommands);
                    }
                    else
                    {
                        Log.LogMessage(ErrorString.SharedCompilationFallback, pathToTool);

                        ExitCode = base.ExecuteTool(pathToTool, responseFileCommands, commandLineCommands);
                    }
                }
            }
            catch (OperationCanceledException)
            {
                ExitCode = 0;
            }
            catch (Exception e)
            {
                Log.LogErrorWithCodeFromResources("Compiler_UnexpectedException");
                LogErrorOutput(e.ToString());
                ExitCode = -1;
            }

            return(ExitCode);
        }
 /// <summary>
 /// The IsConnected property on named pipes does not detect when the client has disconnected
 /// if we don't attempt any new I/O after the client disconnects. We start an async I/O here
 /// which serves to check the pipe for disconnection.
 ///
 /// This will return true if the pipe was disconnected.
 /// </summary>
 protected override Task CreateMonitorDisconnectTask(CancellationToken cancellationToken)
 {
     return(BuildServerConnection.CreateMonitorDisconnectTask(_pipeStream, LoggingIdentifier, cancellationToken));
 }
Ejemplo n.º 7
0
 public void GetPipeNameCore(string expectedName, string userName, bool isAdmin, string compilerExeDir)
 {
     Assert.Equal(expectedName, BuildServerConnection.GetPipeName(userName, isAdmin, compilerExeDir));
 }
Ejemplo n.º 8
0
        /// <summary>
        /// Was a server running with the specified session key during the execution of this call?
        /// </summary>
        private static bool?WasServerRunning(string pipeName)
        {
            string mutexName = BuildServerConnection.GetServerMutexName(pipeName);

            return(BuildServerConnection.WasServerMutexOpen(mutexName));
        }
Ejemplo n.º 9
0
        internal int ExecuteTool(string pathToTool, string responseFileCommands, string commandLineCommands, ICompilerServerLogger logger)
        {
            if (ProvideCommandLineArgs)
            {
                CommandLineArgs = GetArguments(commandLineCommands, responseFileCommands)
                                  .Select(arg => new TaskItem(arg)).ToArray();
            }

            if (SkipCompilerExecution)
            {
                return(0);
            }

            try
            {
                var requestId = Guid.NewGuid();
                logger.Log($"Compilation request {requestId}, PathToTool={pathToTool}");

                string workingDirectory = CurrentDirectoryToUse();
                string?tempDirectory    = BuildServerConnection.GetTempPath(workingDirectory);

                if (!UseSharedCompilation ||
                    HasToolBeenOverridden ||
                    !BuildServerConnection.IsCompilerServerSupported)
                {
                    LogCompilationMessage(logger, requestId, CompilationKind.Tool, $"using command line tool by design '{pathToTool}'");
                    return(base.ExecuteTool(pathToTool, responseFileCommands, commandLineCommands));
                }

                _sharedCompileCts = new CancellationTokenSource();
                logger.Log($"CommandLine = '{commandLineCommands}'");
                logger.Log($"BuildResponseFile = '{responseFileCommands}'");

                var clientDirectory = Path.GetDirectoryName(PathToManagedTool);
                if (clientDirectory is null || tempDirectory is null)
                {
                    LogCompilationMessage(logger, requestId, CompilationKind.Tool, $"using command line tool because we could not find client or temp directory '{PathToManagedTool}'");
                    return(base.ExecuteTool(pathToTool, responseFileCommands, commandLineCommands));
                }

                // Note: using ToolArguments here (the property) since
                // commandLineCommands (the parameter) may have been mucked with
                // (to support using the dotnet cli)
                var buildRequest = BuildServerConnection.CreateBuildRequest(
                    requestId,
                    Language,
                    GetArguments(ToolArguments, responseFileCommands).ToList(),
                    workingDirectory: workingDirectory,
                    tempDirectory: tempDirectory,
                    keepAlive: null,
                    libDirectory: LibDirectoryToUse());

                var pipeName = !string.IsNullOrEmpty(SharedCompilationId)
                    ? SharedCompilationId
                    : BuildServerConnection.GetPipeName(clientDirectory);

                var responseTask = BuildServerConnection.RunServerBuildRequestAsync(
                    buildRequest,
                    pipeName,
                    clientDirectory,
                    logger: logger,
                    cancellationToken: _sharedCompileCts.Token);

                responseTask.Wait(_sharedCompileCts.Token);

                ExitCode = HandleResponse(requestId, responseTask.Result, pathToTool, responseFileCommands, commandLineCommands, logger);
            }
            catch (OperationCanceledException)
            {
                ExitCode = 0;
            }
            catch (Exception e)
            {
                Log.LogErrorWithCodeFromResources("Compiler_UnexpectedException");
                Log.LogErrorFromException(e);
                ExitCode = -1;
            }
            finally
            {
                _sharedCompileCts?.Dispose();
                _sharedCompileCts = null;
            }

            return(ExitCode);
        }
 /// <summary>
 /// The IsConnected property on named pipes does not detect when the client has disconnected
 /// if we don't attempt any new I/O after the client disconnects. We start an async I/O here
 /// which serves to check the pipe for disconnection.
 ///
 /// This will return true if the pipe was disconnected.
 /// </summary>
 private Task MonitorDisconnectAsync(CancellationToken cancellationToken)
 {
     return(BuildServerConnection.MonitorDisconnectAsync(_stream, LoggingIdentifier, cancellationToken));
 }
Ejemplo n.º 11
0
        protected override int ExecuteTool(string pathToTool, string responseFileCommands, string commandLineCommands)
        {
            if (ProvideCommandLineArgs)
            {
                CommandLineArgs = GetArguments(commandLineCommands, responseFileCommands)
                                  .Select(arg => new TaskItem(arg)).ToArray();
            }

            if (SkipCompilerExecution)
            {
                return(0);
            }

            if (!UseSharedCompilation ||
                !string.IsNullOrEmpty(ToolPath) ||
                !BuildServerConnection.IsCompilerServerSupported)
            {
                return(base.ExecuteTool(pathToTool, responseFileCommands, commandLineCommands));
            }

            using (_sharedCompileCts = new CancellationTokenSource())
            {
                try
                {
                    CompilerServerLogger.Log($"CommandLine = '{commandLineCommands}'");
                    CompilerServerLogger.Log($"BuildResponseFile = '{responseFileCommands}'");

                    // Try to get the location of the user-provided build client and server,
                    // which should be located next to the build task. If not, fall back to
                    // "pathToTool", which is the compiler in the MSBuild default bin directory.
                    var clientDir = TryGetClientDir() ?? Path.GetDirectoryName(pathToTool);
                    pathToTool = Path.Combine(clientDir, ToolExe);

                    // Note: we can't change the "tool path" printed to the console when we run
                    // the Csc/Vbc task since MSBuild logs it for us before we get here. Instead,
                    // we'll just print our own message that contains the real client location
                    Log.LogMessage(ErrorString.UsingSharedCompilation, clientDir);

                    var workingDir = CurrentDirectoryToUse();
                    var buildPaths = new BuildPathsAlt(
                        clientDir: clientDir,
                        // MSBuild doesn't need the .NET SDK directory
                        sdkDir: null,
                        workingDir: workingDir,
                        tempDir: BuildServerConnection.GetTempPath(workingDir));

                    var responseTask = BuildServerConnection.RunServerCompilation(
                        Language,
                        GetArguments(commandLineCommands, responseFileCommands).ToList(),
                        buildPaths,
                        keepAlive: null,
                        libEnvVariable: LibDirectoryToUse(),
                        cancellationToken: _sharedCompileCts.Token);

                    responseTask.Wait(_sharedCompileCts.Token);

                    var response = responseTask.Result;
                    if (response != null)
                    {
                        ExitCode = HandleResponse(response, pathToTool, responseFileCommands, commandLineCommands);
                    }
                    else
                    {
                        Log.LogMessage(ErrorString.SharedCompilationFallback, pathToTool);

                        ExitCode = base.ExecuteTool(pathToTool, responseFileCommands, commandLineCommands);
                    }
                }
                catch (OperationCanceledException)
                {
                    ExitCode = 0;
                }
                catch (Exception e)
                {
                    Log.LogErrorWithCodeFromResources("Compiler_UnexpectedException");
                    LogErrorOutput(e.ToString());
                    ExitCode = -1;
                }
            }

            return(ExitCode);
        }
Ejemplo n.º 12
0
 private static string?GetDefaultPipeName()
 {
     return(BuildServerConnection.GetPipeName(BuildClient.GetClientDirectory()));
 }
Ejemplo n.º 13
0
 /// <summary>
 /// The IsConnected property on named pipes does not detect when the client has disconnected
 /// if we don't attempt any new I/O after the client disconnects. We start an async I/O here
 /// which serves to check the pipe for disconnection.
 ///
 /// This will return true if the pipe was disconnected.
 /// </summary>
 private Task CreateMonitorDisconnectTask(CancellationToken cancellationToken)
 {
     return(BuildServerConnection.CreateMonitorDisconnectTask(_stream, LoggingIdentifier, cancellationToken));
 }
Ejemplo n.º 14
0
 public void GetPipeNameCore(string expectedName, string userName, bool isAdmin, string basePipeName)
 {
     Assert.Equal(expectedName, BuildServerConnection.GetPipeNameCore(userName, isAdmin, basePipeName));
 }
Ejemplo n.º 15
0
        protected override int ExecuteTool(
            string pathToTool,
            string responseFileCommands,
            string commandLineCommands
            )
        {
            if (ProvideCommandLineArgs)
            {
                CommandLineArgs = GetArguments(commandLineCommands, responseFileCommands)
                                  .Select(arg => new TaskItem(arg))
                                  .ToArray();
            }

            if (SkipCompilerExecution)
            {
                return(0);
            }

            try
            {
                using var logger = new CompilerServerLogger(
                          $"MSBuild {Process.GetCurrentProcess().Id}"
                          );
                string workingDir = CurrentDirectoryToUse();
                string?tempDir    = BuildServerConnection.GetTempPath(workingDir);
                var    requestId  = Guid.NewGuid();

                if (
                    !UseSharedCompilation ||
                    HasToolBeenOverridden ||
                    !BuildServerConnection.IsCompilerServerSupported
                    )
                {
                    LogCompilationMessage(
                        logger,
                        requestId,
                        CompilationKind.Tool,
                        $"using command line tool by design '{pathToTool}'"
                        );
                    return(base.ExecuteTool(pathToTool, responseFileCommands, commandLineCommands));
                }

                _sharedCompileCts = new CancellationTokenSource();
                logger.Log($"CommandLine = '{commandLineCommands}'");
                logger.Log($"BuildResponseFile = '{responseFileCommands}'");

                var clientDir = Path.GetDirectoryName(PathToManagedTool);
                if (clientDir is null || tempDir is null)
                {
                    LogCompilationMessage(
                        logger,
                        requestId,
                        CompilationKind.Tool,
                        $"using command line tool because we could not find client directory '{PathToManagedTool}'"
                        );
                    return(base.ExecuteTool(pathToTool, responseFileCommands, commandLineCommands));
                }

                var buildPaths = new BuildPathsAlt(
                    clientDir: clientDir,
                    workingDir: workingDir,
                    // MSBuild doesn't need the .NET SDK directory
                    sdkDir: null,
                    tempDir: tempDir
                    );

                // Note: using ToolArguments here (the property) since
                // commandLineCommands (the parameter) may have been mucked with
                // (to support using the dotnet cli)
                var responseTask = BuildServerConnection.RunServerCompilationAsync(
                    requestId,
                    Language,
                    RoslynString.IsNullOrEmpty(SharedCompilationId) ? null : SharedCompilationId,
                    GetArguments(ToolArguments, responseFileCommands).ToList(),
                    buildPaths,
                    keepAlive: null,
                    libEnvVariable: LibDirectoryToUse(),
                    logger: logger,
                    cancellationToken: _sharedCompileCts.Token
                    );

                responseTask.Wait(_sharedCompileCts.Token);

                ExitCode = HandleResponse(
                    requestId,
                    responseTask.Result,
                    pathToTool,
                    responseFileCommands,
                    commandLineCommands,
                    logger
                    );
            }
            catch (OperationCanceledException)
            {
                ExitCode = 0;
            }
            catch (Exception e)
            {
                var util = new TaskLoggingHelper(this);
                util.LogErrorWithCodeFromResources("Compiler_UnexpectedException");
                util.LogErrorFromException(e, showStackTrace: true, showDetail: true, file: null);
                ExitCode = -1;
            }
            finally
            {
                _sharedCompileCts?.Dispose();
                _sharedCompileCts = null;
            }

            return(ExitCode);
        }
 private Task <NamedPipeClientStream> ConnectAsync(CancellationToken cancellationToken = default) => BuildServerConnection.TryConnectToServerAsync(
     _host.PipeName,
     timeoutMs: (int)(TimeSpan.FromMinutes(1).TotalMilliseconds),
     cancellationToken);