diff --git a/src/TraceParserGen/ETWManifest.cs b/src/TraceParserGen/ETWManifest.cs index f67d8075a..51c9ecf11 100644 --- a/src/TraceParserGen/ETWManifest.cs +++ b/src/TraceParserGen/ETWManifest.cs @@ -277,6 +277,7 @@ internal Provider(XmlReader reader, string fileName) { m_taskNames = new Dictionary(); m_taskValues = new Dictionary(); + m_taskGuids = new Dictionary(); } string name = reader.GetAttribute("name"); int value = (int)ParseNumber(reader.GetAttribute("value")); @@ -290,7 +291,12 @@ internal Provider(XmlReader reader, string fileName) m_taskNames.Add(value, message); m_taskValues.Add(name, value); - // Remember enuough to resolve opcodes nested inside this task. + if (Guid.TryParse(reader.GetAttribute("eventGUID"), out var guid)) + { + m_taskGuids.Add(name, guid); + } + + // Remember enough to resolve opcodes nested inside this task. curTask = value; curTaskDepth = reader.Depth; reader.Read(); @@ -556,6 +562,7 @@ private void ReadTemplate(XmlReader reader) private List m_events = new List(); internal string[] m_keywordNames; internal Dictionary m_taskNames; + internal Dictionary m_taskGuids; // Note that the key is task << 8 + opcode to allow for private opcode names internal Dictionary m_opcodeNames; @@ -760,7 +767,7 @@ internal void ResolveIdsInEvent(string fileName = null) if (!m_provider.m_opcodeValues.TryGetValue(Task + ":" + id, out opcode)) opcode = m_provider.m_opcodeValues[id]; - Opcode = (byte) opcode; + Opcode = (byte)opcode; } id = m_keywordsId; @@ -794,7 +801,7 @@ internal void ResolveIdsInEvent(string fileName = null) } } } - catch(Exception) + catch (Exception) { if (fileName == null) { diff --git a/src/TraceParserGen/Properties/launchSettings.json b/src/TraceParserGen/Properties/launchSettings.json new file mode 100644 index 000000000..54aa2e7e3 --- /dev/null +++ b/src/TraceParserGen/Properties/launchSettings.json @@ -0,0 +1,9 @@ +{ + "profiles": { + "TraceParserGen": { + "commandName": "Project", + "commandLineArgs": "\"C:\\Windows\\Microsoft.NET\\Framework\\v4.0.30319\\WPF\\wpf-etw.man\" \"D:\\src\\WpfTraceAnalyzer\\WpfTraceAnalyzer\\WpfTraceParser.cs\"", + "workingDirectory": "D:\\src\\WpfTraceAnalyzer\\WpfTraceAnalyzer" + } + } +} \ No newline at end of file diff --git a/src/TraceParserGen/TraceParserGen.cs b/src/TraceParserGen/TraceParserGen.cs index 7f8e5e1be..cb5d8a087 100644 --- a/src/TraceParserGen/TraceParserGen.cs +++ b/src/TraceParserGen/TraceParserGen.cs @@ -134,6 +134,9 @@ private void GenerateTraceEventParserClass(TextWriter output) // *********** GENERATE EVENTS ********** // GenerateEvents(output); + + GenerateTaskGuids(output); + output.WriteLine(""); output.WriteLine(" #region private"); output.WriteLine(" protected override string GetProviderName() { return ProviderName; }"); @@ -220,8 +223,12 @@ private static string FixKeywordName(string keywordName) keywordName = keywordName.Substring(keywordIdx + 8); } - // Convert it to CamelCase. + if (keywordName.IndexOf('_') < 0) + { + return keywordName; + } + // Convert it to CamelCase. var sb = new StringBuilder(); bool capitalizeNext = true; for (int i = 0; i < keywordName.Length; i++) @@ -249,6 +256,21 @@ private static string FixKeywordName(string keywordName) return sb.ToString(); } + private void GenerateTaskGuids(TextWriter output) + { + var dictionary = m_provider?.m_taskGuids; + if (dictionary == null) + { + return; + } + + foreach (var pair in dictionary) + { + var fieldName = $"{pair.Key}TaskGuid"; + output.WriteLine($" public static readonly Guid {fieldName} = Guid.Parse(\"{pair.Value}\");"); + } + } + /// /// Generate the *Template helper functions as well as the EnumerateTemplates operation. /// @@ -299,12 +321,11 @@ private void GenerateTemplateDefs(TextWriter output) var evnt = m_provider.Events[i]; // check if the same event template has not been already defined (different versions of the same event) - output.WriteLine(" templates[{0}] = new {1}TraceData(null, {2}, {3}, \"{4}\", {4}TaskGuid, {5}, \"{6}\", ProviderGuid, ProviderName);", - i, TraceParserGen.ToCSharpName(evnt.EventName), + output.WriteLine(" templates[{0}] = new {1}(null, {2}, {3}, \"{4}\", {4}TaskGuid, {5}, \"{6}\", ProviderGuid, ProviderName);", + i, + TraceParserGen.GetTemplateNameForEvent(evnt, evnt.TemplateName), evnt.Id, evnt.Task, TraceParserGen.ToCSharpName(evnt.TaskName), evnt.Opcode, TraceParserGen.ToCSharpName(evnt.OpcodeName) ); - // as of today, the generated code won't compile because the task GUID is not defined - // TODO: define the xxxTaskGuid based on eventGUID attribute of elements of the .man file } output.WriteLine(" s_templates = templates;"); @@ -346,7 +367,7 @@ private void GenerateEvents(TextWriter output) var taskName = TraceParserGen.ToCSharpName(evnt.TaskName); if (string.IsNullOrEmpty(taskName)) taskName = evntName; // Call the *Template() function that does the work - output.WriteLine(" RegisterTemplate(new {0}(value, {1}, {2}, \"{3}\", {4}, {5}, \"{6}\", ProviderGuid, ProviderName));", + output.WriteLine(" source.RegisterEventTemplate(new {0}(value, {1}, {2}, \"{3}\", {4}, {5}, \"{6}\", ProviderGuid, ProviderName));", templateClassName, evnt.Id, evnt.Task, taskName, taskGuid, evnt.Opcode, TraceParserGen.ToCSharpName(evnt.OpcodeName) );