зеркало из https://github.com/microsoft/Tx.git
244 строки
9.0 KiB
C#
244 строки
9.0 KiB
C#
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using Tx.Windows;
|
|
|
|
namespace Microsoft.Etw
|
|
{
|
|
internal class Program
|
|
{
|
|
private static string assembly = "";
|
|
private static string outputDirectory = "";
|
|
private static readonly Dictionary<string, string> generated = new Dictionary<string, string>();
|
|
|
|
private static void Main(string[] args)
|
|
{
|
|
Parse(args);
|
|
|
|
if (!String.IsNullOrEmpty(outputDirectory))
|
|
{
|
|
if (!Directory.Exists(outputDirectory))
|
|
{
|
|
Directory.CreateDirectory(outputDirectory);
|
|
}
|
|
}
|
|
|
|
if (String.IsNullOrEmpty(assembly))
|
|
{
|
|
OutputCode();
|
|
}
|
|
else
|
|
{
|
|
string target = Path.Combine(outputDirectory, assembly);
|
|
AssemblyBuilder.OutputAssembly(generated, new string[] { }, target);
|
|
}
|
|
}
|
|
|
|
private static void Parse(string[] args)
|
|
{
|
|
if (args.Length == 0)
|
|
{
|
|
Console.WriteLine(
|
|
@"Usage:
|
|
EtwEventTypeGen [/o:dir] [/a:name] [/m:file] [/e:file] [/t:file] [/w:path]
|
|
|
|
Switches:
|
|
/o:dir Directory for the output.
|
|
If missing, the output is written to the current directory
|
|
|
|
/a:name Generate Assembly.
|
|
If missing the output is C# files.
|
|
|
|
/m:manifest Input from manifest(s)
|
|
/e:etl Input from eventsource etl(s) that contain manifests
|
|
/t:tmf Input from TMF file(s)
|
|
/p:file.blg Input from performance counter trace
|
|
|
|
The switches /o and /a must occur at most once.
|
|
|
|
The switches /m /t can occur many times.
|
|
At least one of these switches must be present
|
|
|
|
Examples:
|
|
|
|
EtwEventTypeGen /m:Microsoft-Windows-HttpService.man
|
|
EtwEventTypeGen /o:c:\Code\EventTypes /m:*.man
|
|
EtwEventTypeGen /a:MyEventTypes /t:c:\tmfs\*.tmf /m:*.man
|
|
EtwEventTypeGen /a:WmiTypes /w:root\wmi\EventTrace\MSNT_SystemTrace
|
|
");
|
|
Environment.Exit(0);
|
|
}
|
|
|
|
foreach (string arg in args)
|
|
{
|
|
string name = arg.Substring(0, 3);
|
|
string value = arg.Substring(3);
|
|
|
|
switch (name)
|
|
{
|
|
case "/a:":
|
|
if (!String.IsNullOrEmpty(assembly))
|
|
{
|
|
Console.WriteLine("The assembly switch /a: occurs more than once.");
|
|
Environment.Exit(1);
|
|
}
|
|
assembly = value;
|
|
break;
|
|
|
|
case "/o:":
|
|
if (!String.IsNullOrEmpty(outputDirectory))
|
|
{
|
|
Console.WriteLine("The output directory switch /o: occurs more than once.");
|
|
Environment.Exit(1);
|
|
}
|
|
outputDirectory = value;
|
|
break;
|
|
|
|
case "/m:":
|
|
string[] manifests;
|
|
string manifestDir = Path.GetDirectoryName(value);
|
|
if (String.IsNullOrEmpty(manifestDir))
|
|
{
|
|
manifests = Directory.GetFiles(".", value);
|
|
}
|
|
else
|
|
{
|
|
manifests = Directory.GetFiles(
|
|
manifestDir,
|
|
Path.GetFileName(value));
|
|
}
|
|
|
|
foreach (string manifest in manifests)
|
|
{
|
|
string content = File.ReadAllText(manifest);
|
|
Dictionary<string, string> code = ManifestParser.Parse(content);
|
|
|
|
foreach (string provider in code.Keys)
|
|
{
|
|
generated.Add(provider, code[provider]);
|
|
}
|
|
}
|
|
break;
|
|
|
|
case "/e:":
|
|
string[] etlFiles;
|
|
string etlDir = Path.GetDirectoryName(value);
|
|
if (String.IsNullOrEmpty(etlDir))
|
|
{
|
|
etlFiles = Directory.GetFiles(".", value);
|
|
}
|
|
else
|
|
{
|
|
etlFiles = Directory.GetFiles(
|
|
etlDir,
|
|
Path.GetFileName(value));
|
|
}
|
|
|
|
foreach (string etlFile in etlFiles)
|
|
{
|
|
string[] etlManifests = ManifestParser.ExtractFromTrace(etlFile);
|
|
|
|
if (etlManifests != null && etlManifests.Length > 0)
|
|
{
|
|
int i = 0;
|
|
foreach (string content in etlManifests)
|
|
{
|
|
Dictionary<string, string> code = ManifestParser.Parse(content);
|
|
|
|
foreach (string provider in code.Keys)
|
|
{
|
|
generated.Add(provider, code[provider]);
|
|
}
|
|
|
|
// Write the manifest text file
|
|
using (TextWriter wr =
|
|
new StreamWriter(Path.Combine(outputDirectory, Path.GetFileNameWithoutExtension(etlFile) + "_" + i.ToString() + ".man")))
|
|
{
|
|
wr.Write(content);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Console.WriteLine("No manifest found in file:{0}", etlFile);
|
|
}
|
|
}
|
|
break;
|
|
|
|
case "/t:":
|
|
string[] tmfs;
|
|
string tmfDir = Path.GetDirectoryName(value);
|
|
if (String.IsNullOrEmpty(tmfDir))
|
|
{
|
|
tmfs = Directory.GetFiles(".", value);
|
|
}
|
|
else
|
|
{
|
|
tmfs = Directory.GetFiles(
|
|
tmfDir,
|
|
Path.GetFileName(value));
|
|
}
|
|
|
|
foreach (string tmf in tmfs)
|
|
{
|
|
Console.WriteLine(tmf);
|
|
string provider = Path.GetFileNameWithoutExtension(tmf);
|
|
string code = TmfParser.Parse(tmf);
|
|
generated.Add(provider, code);
|
|
}
|
|
break;
|
|
|
|
case "/p:":
|
|
string[] perfTraces;
|
|
string perfDir = Path.GetDirectoryName(value);
|
|
if (String.IsNullOrEmpty(perfDir))
|
|
{
|
|
perfTraces = Directory.GetFiles(".", value);
|
|
}
|
|
else
|
|
{
|
|
perfTraces = Directory.GetFiles(
|
|
perfDir,
|
|
Path.GetFileName(value));
|
|
}
|
|
|
|
foreach (string perfTrace in perfTraces)
|
|
{
|
|
Console.WriteLine(perfTrace);
|
|
Dictionary<string, string> code = PerfCounterParser.Parse(perfTrace);
|
|
|
|
foreach (string provider in code.Keys)
|
|
{
|
|
generated.Add(provider, code[provider]);
|
|
}
|
|
}
|
|
break;
|
|
|
|
case "/w:":
|
|
Console.WriteLine("The WMI switch /w: is not yet implemented.");
|
|
Environment.Exit(2);
|
|
break;
|
|
|
|
default:
|
|
Console.WriteLine("Unknown switch " + arg);
|
|
Environment.Exit(1);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
private static void OutputCode()
|
|
{
|
|
foreach (string provider in generated.Keys)
|
|
{
|
|
using (TextWriter wr = new StreamWriter(Path.Combine(outputDirectory, provider + ".cs")))
|
|
{
|
|
wr.Write(generated[provider]);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|