/// <summary> /// Creates an instance of this class for the specified task. /// </summary> public TaskEngine ( XmlElement taskNodeXmlElement, ITaskHost hostObject, string projectFileOfTaskNode, string parentProjectFullFileName, EngineLoggingServices loggingServices, int handleId, TaskExecutionModule parentModule, BuildEventContext targetBuildEventContext ) { ErrorUtilities.VerifyThrow(taskNodeXmlElement != null, "Need to specify the task node."); ErrorUtilities.VerifyThrow(projectFileOfTaskNode != null, "Need to specify path of project."); ErrorUtilities.VerifyThrow(parentProjectFullFileName != null, "Need to specify name of project."); ErrorUtilities.VerifyThrow(loggingServices != null, "Need to specify the node logger."); this.taskNode = taskNodeXmlElement; this.taskClass = null; this.hostObject = hostObject; this.projectFileOfTaskNode = projectFileOfTaskNode; this.parentProjectFullFileName = parentProjectFullFileName; this.loggingServices = loggingServices; this.handleId = handleId; this.parentModule = parentModule; this.continueOnError = false; this.conditionAttribute = taskNode.Attributes[XMakeAttributes.condition]; this.buildEventContext = targetBuildEventContext; }
/// <summary> /// Log a comment /// </summary> /// <param name="buildEventContext">Event context information which describes who is logging the event</param> /// <param name="importance">How important is the message, this will determine which verbosities the message will show up on. /// The higher the importance the lower the verbosity needs to be for the message to be seen</param> /// <param name="message">Message to log</param> /// <exception cref="InternalErrorException">BuildEventContext is null</exception> /// <exception cref="InternalErrorException">Message is null</exception> public void LogCommentFromText(BuildEventContext buildEventContext, MessageImportance importance, string message) { lock (_lockObject) { this.LogCommentFromText(buildEventContext, importance, message, null); } }
internal TargetExecutionWrapper ( Target targetClass, ArrayList taskElementList, List<string> targetParameters, XmlElement targetElement, Expander expander, BuildEventContext targetBuildEventContext ) { // Initialize the data about the target XML that has been calculated in the target class this.targetClass = targetClass; this.parentEngine = targetClass.ParentEngine; this.parentProject = targetClass.ParentProject; this.targetElement = targetElement; this.taskElementList = taskElementList; this.targetParameters = targetParameters; this.targetBuildEventContext = targetBuildEventContext; // Expand the list of depends on targets dependsOnTargetNames = expander.ExpandAllIntoStringList(targetClass.DependsOnTargets, targetClass.DependsOnTargetsAttribute); // Starting to build the target inProgressBuildState = InProgressBuildState.StartingBuild; // No messages have been logged loggedTargetStart = false; }
/// <summary> /// The constructor obtains the state information and the /// callback delegate. /// </summary> internal TaskExecutionState ( TaskExecutionMode howToExecuteTask, Lookup lookupForInference, Lookup lookupForExecution, XmlElement taskXmlNode, ITaskHost hostObject, string projectFileOfTaskNode, string parentProjectFullFileName, string executionDirectory, int handleId, BuildEventContext buildEventContext ) { ErrorUtilities.VerifyThrow(taskXmlNode != null, "Must have task node"); this.howToExecuteTask = howToExecuteTask; this.lookupForInference = lookupForInference; this.lookupForExecution = lookupForExecution; this.hostObject = hostObject; this.projectFileOfTaskNode = projectFileOfTaskNode; this.parentProjectFullFileName = parentProjectFullFileName; this.executionDirectory = executionDirectory; this.handleId = handleId; this.buildEventContext = buildEventContext; this.taskXmlNode = taskXmlNode; }
/// <summary> /// Constructs a logging context from another logging context. This is used primarily in /// the constructors for other logging contexts to populate the logging service parameter, /// while the event context will come from a call into the logging service itself. /// </summary> /// <param name="baseContext">The context from which this context is being created.</param> protected BaseLoggingContext(BaseLoggingContext baseContext) { _loggingService = baseContext._loggingService; _eventContext = null; _isValid = baseContext._isValid; _isInProcNode = baseContext._isInProcNode; }
public static void FixtureSetup(TestContext testContext) { BuildEventContext context = new BuildEventContext(1, 2, 3, 4); s_error.BuildEventContext = context; s_warning.BuildEventContext = context; s_targetStarted.BuildEventContext = context; s_targetFinished.BuildEventContext = context; }
internal static void Throw(Exception innerException, BuildEventContext buildEventContext, string messageResourceName, params string[] messageArgs) { ErrorUtilities.VerifyThrow(messageResourceName != null, "Need error message."); string message = ResourceUtilities.FormatResourceString(messageResourceName, messageArgs); throw new RemoteErrorException(message, innerException, buildEventContext); }
public ConfigureableForwardingLogger_Tests() { BuildEventContext context = new BuildEventContext(1, 2, 3, 4); _error.BuildEventContext = context; _warning.BuildEventContext = context; _targetStarted.BuildEventContext = context; _targetFinished.BuildEventContext = context; }
/// <summary> /// Create a build request from the list of targets to build and build request object /// </summary> internal ProjectBuildState(BuildRequest buildRequest, ArrayList targetNamesToBuild, BuildEventContext buildEventContext) { this.buildRequest = buildRequest; this.indexOfTargetInProgress = 0; this.targetNamesToBuild = targetNamesToBuild; this.buildContextState = BuildContextState.StartingFirstTarget; this.projectBuildEventContext = buildEventContext; }
internal RemoteErrorException(string message, Exception innerException, BuildEventContext buildEventContext) : base(message, innerException) { ErrorUtilities.VerifyThrow((message != null) && (message.Length > 0), "Need error message."); ErrorUtilities.VerifyThrow(innerException != null, "Need the logger exception."); this.buildEventContext = buildEventContext; }
public void FixtureSetup() { BuildEventContext context = new BuildEventContext(1, 2, 3, 4); error.BuildEventContext = context; warning.BuildEventContext = context; targetStarted.BuildEventContext = context; targetFinished.BuildEventContext = context; }
protected BuildEventArgs (string message, string helpKeyword, string senderName, DateTime eventTimestamp) { this.message = message; this.helpKeyword = helpKeyword; this.senderName = senderName; this.threadId = Thread.CurrentThread.GetHashCode (); this.timestamp = eventTimestamp; this.context = BuildEventContext.NewInstance (); }
/// <summary> /// Constructs the logging context from a logging service and an event context. /// </summary> /// <param name="loggingService">The logging service to use</param> /// <param name="eventContext">The event context</param> /// <param name="inProc">Flag indicating if this context belongs to an in-proc node.</param> protected BaseLoggingContext(ILoggingService loggingService, BuildEventContext eventContext, bool inProc) { ErrorUtilities.VerifyThrowArgumentNull(loggingService, "loggingService"); ErrorUtilities.VerifyThrowArgumentNull(eventContext, "eventContext"); _loggingService = loggingService; _eventContext = eventContext; _isValid = false; _isInProcNode = inProc; }
internal void AddProjectStartedEvent(string projectFile, BuildEventContext context) { lock (this.projectStartedEvents) { if (!this.projectStartedEvents.ContainsKey(context)) { this.projectStartedEvents.Add(context, projectFile); } } }
internal string GetProjectFile(BuildEventContext e) { string file; lock (projectStartedEvents) { projectStartedEvents.TryGetValue(e, out file); } return file; }
/// <summary> /// Given the full path to a solution, returns a string containing the v3.5 MSBuild-format /// wrapper project for that solution. /// </summary> /// <param name="solutionPath">Full path to the solution we are wrapping</param> /// <param name="toolsVersionOverride">May be null. If non-null, contains the ToolsVersion passed in on the command line</param>\ /// <param name="projectBuildEventContext">An event context for logging purposes.</param> /// <returns></returns> static public string Generate(string solutionPath, string toolsVersionOverride, BuildEventContext projectBuildEventContext) { Project msbuildProject = new Project(); SolutionParser solution = new SolutionParser(); solution.SolutionFile = solutionPath; solution.ParseSolutionFile(); Generate(solution, msbuildProject, toolsVersionOverride, projectBuildEventContext); return msbuildProject.Xml; }
/// <summary> /// Logs a comment (BuildMessageEventArgs) with a certain MessageImportance level /// </summary> /// <param name="buildEventContext">Event context information which describes who is logging the event</param> /// <param name="importance">How important is the message, this will determine which verbosities the message will show up on. /// The higher the importance the lower the verbosity needs to be for the message to be seen</param> /// <param name="messageResourceName">String which identifies the message in the string resx</param> /// <param name="messageArgs">Arguments for the format string indexed by messageResourceName</param> /// <exception cref="InternalErrorException">MessageResourceName is null</exception> public void LogComment(BuildEventContext buildEventContext, MessageImportance importance, string messageResourceName, params object[] messageArgs) { lock (_lockObject) { if (!OnlyLogCriticalEvents) { ErrorUtilities.VerifyThrow(!string.IsNullOrEmpty(messageResourceName), "Need resource string for comment message."); LogCommentFromText(buildEventContext, importance, ResourceUtilities.GetResourceString(messageResourceName), messageArgs); } } }
/// <summary> /// Creates an instance of this class for the given target. /// </summary> /// <owner>SumedhK</owner> internal TargetDependencyAnalyzer(string projectDirectory, Target targetToAnalyze, EngineLoggingServices loggingServices, BuildEventContext buildEventContext) { ErrorUtilities.VerifyThrow(projectDirectory != null, "Need a project directory."); ErrorUtilities.VerifyThrow(targetToAnalyze != null, "Need a target to analyze."); ErrorUtilities.VerifyThrow(targetToAnalyze.TargetElement != null, "Need a target element."); this.projectDirectory = projectDirectory; this.targetToAnalyze = targetToAnalyze; this.targetInputsAttribute = targetToAnalyze.TargetElement.Attributes[XMakeAttributes.inputs]; this.targetOutputsAttribute = targetToAnalyze.TargetElement.Attributes[XMakeAttributes.outputs]; this.loggingService = loggingServices; this.buildEventContext = buildEventContext; }
/// <summary> /// This constructor allows event data to be initialized. /// Sender is assumed to be "MSBuild". /// </summary> /// <param name="projectId">project id</param> /// <param name="message">text message</param> /// <param name="helpKeyword">help keyword </param> /// <param name="projectFile">project name</param> /// <param name="targetNames">targets we are going to build (empty indicates default targets)</param> /// <param name="properties">list of properties</param> /// <param name="items">list of items</param> /// <param name="parentBuildEventContext">event context info for the parent project</param> public ProjectStartedEventArgs ( int projectId, string message, string helpKeyword, string projectFile, string targetNames, IEnumerable properties, IEnumerable items, BuildEventContext parentBuildEventContext ) : this(projectId, message, helpKeyword, projectFile, targetNames, properties, items, parentBuildEventContext, DateTime.UtcNow) { }
internal override void CreateFromStream(BinaryReader reader) { base.CreateFromStream(reader); this.projectId = reader.ReadInt32(); if (reader.ReadByte() == 0) { this.parentProjectBuildEventContext = null; } else { int nodeId = reader.ReadInt32(); int submissionId = reader.ReadInt32(); int projectInstanceId = reader.ReadInt32(); int projectContextId = reader.ReadInt32(); int targetId = reader.ReadInt32(); int taskId = reader.ReadInt32(); this.parentProjectBuildEventContext = new BuildEventContext(submissionId, nodeId, projectInstanceId, projectContextId, targetId, taskId); } if (reader.ReadByte() == 0) { this.projectFile = null; } else { this.projectFile = reader.ReadString(); } this.targetNames = reader.ReadString(); if (reader.ReadByte() == 0) { this.properties = null; } else { int capacity = reader.ReadInt32(); ArrayList list = new ArrayList(capacity); for (int i = 0; i < capacity; i++) { string key = reader.ReadString(); string str2 = reader.ReadString(); if ((key != null) && (str2 != null)) { DictionaryEntry entry = new DictionaryEntry(key, str2); list.Add(entry); } } this.properties = list; } }
public void Compare () { Assert.IsTrue (BuildEventContext.Invalid == BuildEventContext.Invalid, "#1"); Assert.IsFalse (BuildEventContext.Invalid != BuildEventContext.Invalid, "#2"); var inst = new BuildEventContext (0, 0, 0, 0); Assert.IsFalse (BuildEventContext.Invalid == inst, "#3"); Assert.IsTrue (BuildEventContext.Invalid != inst, "#4"); Assert.IsFalse (BuildEventContext.Invalid == null, "#5"); Assert.IsTrue (BuildEventContext.Invalid != null, "#6"); Assert.IsFalse (BuildEventContext.Invalid.Equals (null), "#7"); Assert.IsFalse (BuildEventContext.Invalid.Equals (inst), "#8"); Assert.IsTrue (BuildEventContext.Invalid.Equals (BuildEventContext.Invalid), "#9"); Assert.IsFalse (inst.Equals (null), "#10"); Assert.IsTrue (inst.Equals (inst), "#11"); Assert.IsFalse (inst.Equals (BuildEventContext.Invalid), "#12"); }
/// <summary> /// Override to BuildProject file to return true so we can test that /// </summary> override internal bool BuildProjectFile ( int nodeProxyId, string[] projectFileNames, string[] targetNames, IDictionary[] globalProperties, IDictionary[] targetOutputsPerProject, EngineLoggingServices loggingServices, string[] toolsVersions, bool useResultsCache, bool unloadProjectsOnCompletion, BuildEventContext taskContext ) { return true; }
/// <summary> /// This method generates an XmlDocument representing an MSBuild project file from the list of /// projects and project dependencies that have been collected from the solution file. /// </summary> /// <param name="solution"></param> /// <param name="msbuildProject"></param> /// <param name="toolsVersionOverride">Tools Version override (may be null). /// Any /tv:xxx switch would cause a value here.</param> /// <returns></returns> /// <owner>RGoel</owner> static internal void Generate(SolutionParser solution, Project msbuildProject, string toolsVersionOverride, BuildEventContext projectBuildEventContext) { // Validate against our minimum for upgradable projects ProjectFileErrorUtilities.VerifyThrowInvalidProjectFile((solution.Version >= SolutionParser.slnFileMinVersion), "SubCategoryForSolutionParsingErrors", new BuildEventFileInfo(solution.SolutionFile), "SolutionParseUpgradeNeeded"); // Although we only return an XmlDocument back, we need to make decisions about tools versions because // we have to choose what <UsingTask> tags to put in, whether to put a ToolsVersion parameter // on <MSBuild> task tags, and what MSBuildToolsPath to use when scanning child projects // for dependency information. string wrapperProjectToolsVersion = DetermineWrapperProjectToolsVersion(toolsVersionOverride); msbuildProject.DefaultTargets = "Build"; msbuildProject.DefaultToolsVersion = wrapperProjectToolsVersion; Engine parentEngine = msbuildProject.ParentEngine; string solutionProjectCache = solution.SolutionFile + ".cache"; bool? upToDate = LoadCache(solution, msbuildProject, projectBuildEventContext, wrapperProjectToolsVersion, parentEngine, solutionProjectCache); if (upToDate == true) { // Cache exists, was loaded, and was up to date: we're done return; } // Cache didn't exist or wasn't up to date; generate a new one Project solutionProject = msbuildProject; if (upToDate == false) { // We have already loaded a cache file we can't use; we need to work in a new project object solutionProject = CreateNewProject(solution, wrapperProjectToolsVersion, parentEngine, solutionProject); } CreateSolutionProject(solution, solutionProject, projectBuildEventContext, wrapperProjectToolsVersion, parentEngine, solutionProjectCache); if (upToDate == false) { // Put the contents of the new project object into the one we were passed msbuildProject.LoadFromXmlDocument(solutionProject.XmlDocument, projectBuildEventContext, msbuildProject.LoadSettings); } // Write a new cache file, hopefully we can use it next time UpdateCache(parentEngine, msbuildProject, solutionProjectCache, projectBuildEventContext); }
/// <summary> /// Writes a plan for the specified submission id. /// </summary> public void WritePlan(int submissionId, ILoggingService loggingService, BuildEventContext buildEventContext) { if (!BuildParameters.EnableBuildPlan) { return; } SchedulableRequest rootRequest = GetRootRequest(submissionId); if (rootRequest == null) { return; } string planName = GetPlanName(rootRequest); if (String.IsNullOrEmpty(planName)) { return; } try { using (StreamWriter file = new StreamWriter(File.Open(planName, FileMode.Create))) { // Write the accumulated configuration times. Dictionary<int, double> accumulatedTimeByConfiguration = new Dictionary<int, double>(); RecursiveAccumulateConfigurationTimes(rootRequest, accumulatedTimeByConfiguration); List<int> configurationsInOrder = new List<int>(accumulatedTimeByConfiguration.Keys); configurationsInOrder.Sort(); foreach (int configId in configurationsInOrder) { file.WriteLine(String.Format(CultureInfo.InvariantCulture, "{0} {1} {2}", configId, accumulatedTimeByConfiguration[configId], _configCache[configId].ProjectFullPath)); } file.WriteLine(); // Write out the dependency information. RecursiveWriteDependencies(file, rootRequest); } } catch (IOException) { loggingService.LogCommentFromText(buildEventContext, MessageImportance.Low, ResourceUtilities.FormatResourceString("CantWriteBuildPlan", planName)); } }
/// <summary> /// Default constructor for creation of task execution wrapper /// </summary> internal TaskExecutionContext ( Project parentProject, Target parentTarget, XmlElement taskNode, ProjectBuildState buildContext, int handleId, int nodeIndex, BuildEventContext taskBuildEventContext ) :base(handleId, nodeIndex, taskBuildEventContext) { this.parentProject = parentProject; this.parentTarget = parentTarget; this.taskNode = taskNode; this.buildContext = buildContext; this.thrownException = null; }
/// <summary> /// Default constructor for a routing context /// </summary> internal RequestRoutingContext ( int handleId, int nodeIndex, int parentHandleId, int parentNodeIndex, int parentRequestId, CacheScope cacheScope, BuildRequest triggeringBuildRequest, BuildEventContext buildEventContext ) :base(handleId, nodeIndex, buildEventContext) { this.parentHandleId = parentHandleId; this.parentNodeIndex = parentNodeIndex; this.parentRequestId = parentRequestId; this.cacheScope = cacheScope; this.triggeringBuildRequest = triggeringBuildRequest; }
/// <summary> /// Log a comment /// </summary> /// <param name="buildEventContext">Event context information which describes who is logging the event</param> /// <param name="importance">How important is the message, this will determine which verbosities the message will show up on. /// The higher the importance the lower the verbosity needs to be for the message to be seen</param> /// <param name="message">Message to log</param> /// <param name="messageArgs">Message formatting arguments</param> /// <exception cref="InternalErrorException">BuildEventContext is null</exception> /// <exception cref="InternalErrorException">Message is null</exception> public void LogCommentFromText(BuildEventContext buildEventContext, MessageImportance importance, string message, params object[] messageArgs) { lock (_lockObject) { if (!OnlyLogCriticalEvents) { ErrorUtilities.VerifyThrow(buildEventContext != null, "buildEventContext was null"); ErrorUtilities.VerifyThrow(message != null, "message was null"); BuildMessageEventArgs buildEvent = new BuildMessageEventArgs ( message, null, "MSBuild", importance, DateTime.UtcNow, messageArgs ); buildEvent.BuildEventContext = buildEventContext; ProcessLoggingEvent(buildEvent); } } }
/// <summary> /// Creates an IntrinsicTask object around a "task" node /// </summary> internal IntrinsicTask(XmlElement taskNodeXmlElement, EngineLoggingServices loggingServices, BuildEventContext eventContext, string executionDirectory, ItemDefinitionLibrary itemDefinitionLibrary) { this.taskNodeXmlElement = taskNodeXmlElement; this.conditionAttribute = taskNodeXmlElement.Attributes[XMakeAttributes.condition]; this.loggingServices = loggingServices; this.buildEventContext = eventContext; this.executionDirectory = executionDirectory; this.itemDefinitionLibrary = itemDefinitionLibrary; ErrorUtilities.VerifyThrow(IsIntrinsicTaskName(taskNodeXmlElement.Name), "Only PropertyGroup and ItemGroup are known intrinsic tasks"); switch (taskNodeXmlElement.Name) { case XMakeElements.propertyGroup: backingType = BackingType.PropertyGroup; // If the backing type is a property group, we can just use a property group object; its semantics aren't // tangled up with the project object. Put another way, we only really need the code that understands the XML // format of a property group, and we can get that without the rest of BuildPropertyGroup getting in the way. // Specify that these properties are output properties, so they get reverted when the project is reset. backingPropertyGroup = new BuildPropertyGroup(null /* no parent project */, taskNodeXmlElement, PropertyType.OutputProperty); break; case XMakeElements.itemGroup: backingType = BackingType.ItemGroup; // If the backing type is an item group, we just re-use the code that understands the XML format of an item group; // the semantics of BuildItemGroup are too coupled to its current use in the Project object for us to re-use it. backingItemGroupXml = new BuildItemGroupXml(taskNodeXmlElement); List<XmlElement> children = backingItemGroupXml.GetChildren(); backingBuildItemGroupChildren = new List<BuildItemGroupChildXml>(children.Count); foreach (XmlElement child in children) { BuildItemGroupChildXml childXml = new BuildItemGroupChildXml(child, ChildType.Any); backingBuildItemGroupChildren.Add(childXml); } break; } }
public ProjectStartedEventArgs(int projectId, string message, string helpKeyword, string projectFile, string targetNames, IEnumerable properties, IEnumerable items, BuildEventContext parentBuildEventContext) : this(projectId, message, helpKeyword, projectFile, targetNames, properties, items, parentBuildEventContext, DateTime.UtcNow) { }
public ProjectStartedEventArgs(int projectId, string message, string helpKeyword, string projectFile, string targetNames, IEnumerable properties, IEnumerable items, BuildEventContext parentBuildEventContext, DateTime eventTimestamp) : this(message, helpKeyword, projectFile, targetNames, properties, items, eventTimestamp) { this.parentProjectBuildEventContext = parentBuildEventContext; this.projectId = projectId; }
private void SetDefaultsBeforeSerialization(StreamingContext sc) { this.projectId = -1; this.parentProjectBuildEventContext = null; }
private bool InternalEquals(BuildEventContext buildEventContext) { return((((this.nodeId == buildEventContext.NodeId) && (this.projectContextId == buildEventContext.ProjectContextId)) && (this.targetId == buildEventContext.TargetId)) && (this.taskId == buildEventContext.TaskId)); }
/// <summary> /// Deserializes from a stream through a binary reader /// </summary> /// <param name="reader">Binary reader which is attached to the stream the event will be deserialized from</param> /// <param name="version">The version of the runtime the message packet was created from</param> internal override void CreateFromStream(BinaryReader reader, int version) { base.CreateFromStream(reader, version); projectId = reader.ReadInt32(); if (reader.ReadByte() == 0) { parentProjectBuildEventContext = null; } else { int nodeId = reader.ReadInt32(); int projectContextId = reader.ReadInt32(); int targetId = reader.ReadInt32(); int taskId = reader.ReadInt32(); if (version > 20) { int submissionId = reader.ReadInt32(); int projectInstanceId = reader.ReadInt32(); parentProjectBuildEventContext = new BuildEventContext(submissionId, nodeId, projectInstanceId, projectContextId, targetId, taskId); } else { parentProjectBuildEventContext = new BuildEventContext(nodeId, targetId, projectContextId, taskId); } } projectFile = reader.ReadByte() == 0 ? null : reader.ReadString(); // TargetNames cannot be null as per the constructor targetNames = reader.ReadString(); // Check to see if properties was null if (reader.ReadByte() == 0) { properties = null; } else { // Get number of properties put on the stream int numberOfProperties = reader.ReadInt32(); // We need to use a dictionaryEntry as that is what the old behavior was ArrayList dictionaryList = new ArrayList(numberOfProperties); // Read off each of the key value pairs and put them into the dictionaryList for (int i = 0; i < numberOfProperties; i++) { string key = reader.ReadString(); string value = reader.ReadString(); if (key != null && value != null) { DictionaryEntry entry = new DictionaryEntry(key, value); dictionaryList.Add(entry); } } properties = dictionaryList; } }
private void SetBuildEventContextDefaultBeforeSerialization(StreamingContext sc) { // Don't want to create a new one here as default all the time as that would be a lot of // possibly useless allocations buildEventContext = null; }
/// <summary> /// Deserializes from a stream through a binary reader /// </summary> /// <param name="reader">Binary reader which is attached to the stream the event will be deserialized from</param> /// <param name="version">The version of the runtime the message packet was created from</param> internal virtual void CreateFromStream(BinaryReader reader, int version) { #region Message if (reader.ReadByte() == 0) { message = null; } else { message = reader.ReadString(); } #endregion #region HelpKeyword if (reader.ReadByte() == 0) { helpKeyword = null; } else { helpKeyword = reader.ReadString(); } #endregion #region SenderName if (reader.ReadByte() == 0) { senderName = null; } else { senderName = reader.ReadString(); } #endregion #region TimeStamp long timestampTicks = reader.ReadInt64(); if (version > 20) { DateTimeKind kind = (DateTimeKind)reader.ReadInt32(); timestamp = new DateTime(timestampTicks, kind); } else { timestamp = new DateTime(timestampTicks); } #endregion threadId = reader.ReadInt32(); #region BuildEventContext if (reader.ReadByte() == 0) { buildEventContext = null; } else { int nodeId = reader.ReadInt32(); int projectContextId = reader.ReadInt32(); int targetId = reader.ReadInt32(); int taskId = reader.ReadInt32(); if (version > 20) { int submissionId = reader.ReadInt32(); int projectInstanceId = reader.ReadInt32(); buildEventContext = new BuildEventContext(submissionId, nodeId, projectInstanceId, projectContextId, targetId, taskId); } else { buildEventContext = new BuildEventContext(nodeId, targetId, projectContextId, taskId); } } #endregion }