/// <summary> /// Main entry point for the process. Initialize the server dispatcher /// and wait for connections. /// </summary> public static int Main(string[] args) { CompilerServerLogger.Initialize("SRV"); CompilerServerLogger.Log("Process started"); TimeSpan?keepAliveTimeout = null; try { int keepAliveValue; string keepAliveStr = ConfigurationManager.AppSettings["keepalive"]; if (int.TryParse(keepAliveStr, NumberStyles.Integer, CultureInfo.InvariantCulture, out keepAliveValue) && keepAliveValue >= 0) { if (keepAliveValue == 0) { // This is a one time server entry. keepAliveTimeout = null; } else { keepAliveTimeout = TimeSpan.FromSeconds(keepAliveValue); } } else { keepAliveTimeout = s_defaultServerKeepAlive; } } catch (ConfigurationErrorsException e) { keepAliveTimeout = s_defaultServerKeepAlive; CompilerServerLogger.LogException(e, "Could not read AppSettings"); } CompilerServerLogger.Log("Keep alive timeout is: {0} milliseconds.", keepAliveTimeout?.TotalMilliseconds ?? 0); FatalError.Handler = FailFast.OnFatalException; // VBCSCompiler is installed in the same directory as csc.exe and vbc.exe which is also the // location of the response files. var responseFileDirectory = CommonCompiler.GetResponseFileDirectory(); var dispatcher = new ServerDispatcher(new CompilerRequestHandler(responseFileDirectory), new EmptyDiagnosticListener()); // Add the process ID onto the pipe name so each process gets a semi-unique and predictable pipe // name. The client must use this algorithm too to connect. string pipeName = BuildProtocolConstants.PipeName + Process.GetCurrentProcess().Id.ToString(); dispatcher.ListenAndDispatchConnections(pipeName, keepAliveTimeout, watchAnalyzerFiles: true); return(0); }