TraceParserGen A ProviderManifest represents the XML manifest associated with the provider. The name of the ETW provider The GUID that uniquely identifies the ETW provider The events for the returns the name of the keyword which has the bit position bitPos (bitPos is 0 through 63). It may return null if there is no keyword name for 'bitPos'. returns a string that is the best human readable representation of the keyword set represented by 'keywords'. It the concatenation of all the keyword names separated by a comma, as well as a hexadecimal number (if there is anything that can't be represented by names). For debugging Read a ProviderManifest from a stream Adds an opcode with a given name to the database. 'taskId' can be GlobalScope if the opcode works for any task. 'manifestName' is the name in the manifest (e.g. "win:Stop") and 'name' is the name that you will print (e.g. "Stop"). If manifestName is null then name and manifest name are considered the same. An event represents the Event Element in the manifest. It describes the meta-data of one ETW event A convenience method that returns the keywords as symbol names (comma separated) The fields associated with this event. This can be null if there are no fields. The event name is synthesis (concatenation) of the Task and Opcode names. This is never null. Technically the Symbol attribute on an event is not part of the model (it is not stored in the binary manifest) but if it is present, it can be used to create better names. This value can be null. Technically the name of the Template for the fields on an event is not part of the model (it is not stored in the binary manifest) but if it is present, it can be used to create better names. This value can be null. Get the line number in the file. Used for error messages. We need a two pass system where after all the definitions are parsed, we go back and link up uses to their defs. This routine does this for Events. A field represents one field in a ETW event The name of the field. If the type is a structure, then this points at its type. 'Enumeration' and 'Type' will be null in this case. If Type is a integral type, then Enumeration can be set which gives values either a bitfield or a enumerated type for the values of the parameter. Otherwise it is null. If the type is 'built in' then it has a string name, and this is it. This is null for structs and an integer type for Enumerations. There is no Array type. Instead all field can have a 'Count' which might be a number (for fixed sized arrays) or a name of a Field (for variable sized arrays). This can be null, which means the field is not an array. If set, it indicates that the integer value should be pretty-printed as hexadecimal rather than decimal. A struct represents a composite type and can be used in field definitions Then name of the type of the structure as a whole. A Enumeration represents an enumerated type and can be used in field definitions. Things that really should be in System.Array but aren't Concatinate two arrays and return the new array result. Concatinated array. Return a new array that has a range of elements removed. The array to removed elements from. It is NOT modified. The index of the first element that will be removed. The number of elements to be removed. The shorted array. Return a new array where a range as been removed and replace with a range from another array. The source array to be manipulated. It is NOT modified. The first element of sourceArray to remove. The number of elements to remove. Elements after this exist in the return array The array that will provide the elements to splice into soruceArray. The first element in insertArray to splice in. The number of elements from insertArray to splice in. The new array that has had the removal range replaced with the insert range. CommandOptions is a helper class for the Command class. It stores options that affect the behavior of the execution of Commands and is passes as a parapeter to the constuctor of a Command. It is useful for these options be be on a separate class (rather than on Command itself), because it is reasonably common to want to have a set of options passed to several commands, which is not easily possible otherwise. Can be assigned to the Timeout Property to indicate infinite timeout. CommanOptions holds a set of options that can be passed to the constructor to the Command Class as well as Command.Run* Return a copy an existing set of command options The copy of the command options Normally commands will throw if the subprocess returns a non-zero exit code. NoThrow suppresses this. Updates the NoThrow propery and returns the updated commandOptions. Updated command options Normally commands are launched with CreateProcess. However it is also possible use the Shell Start API. This causes Command to look up the executable differnetly as well as no wait for the command to compete before returning. Updates the Start propery and returns the updated commandOptions. By default commands have a 10 minute timeout (600,000 msec), If this is inappropriate, the Timeout property can change this. Like all timouts in .NET, it is in units of milliseconds, and you can use CommandOptions.Infinite to indicate no timeout. Updates the Timeout propery and returns the updated commandOptions. Indicates the string will be sent to Console.In for the subprocess. Updates the Input propery and returns the updated commandOptions. Indicates the current directory the subProcess will have. Updates the CurrentDirectory propery and returns the updated commandOptions. Indicates the standard output and error of the command should be redirected to a archiveFile rather than being stored in memory in the 'Output' property of the command. Updates the OutputFile propery and returns the updated commandOptions. Indicates the standard output and error of the command should be redirected to a a TextWriter rather than being stored in memory in the 'Output' property of the command. Updates the OutputStream propery and returns the updated commandOptions. Gets the Environment variables that will be set in the subprocess that differ from current process's environment variables. Any time a string of the form %VAR% is found in a value of a environment variable it is replaced with the value of the environment variable at the time the command is launched. This is useful for example to update the PATH environment variable eg. "%PATH%;someNewPath" Adds the environment variable with the give value to the set of environmetn variables to be passed to the sub-process and returns the updated commandOptions. Any time a string of the form %VAR% is found in a value of a environment variable it is replaced with the value of the environment variable at the time the command is launched. This is useful for example to update the PATH environment variable eg. "%PATH%;someNewPath" Command represents a running of a command lineNumber process. It is basically a wrapper over System.Diagnostics.Process, which hides the complexitity of System.Diagnostics.Process, and knows how to capture output and otherwise makes calling commands very easy. The time the process started. returns true if the process has exited. The time the processed Exited. (HasExited should be true before calling) The duration of the command (HasExited should be true before calling) The operating system ID for the subprocess. The process exit code for the subprocess. (HasExited should be true before calling) Often this does not need to be checked because Command.Run will throw an exception if it is not zero. However it is useful if the CommandOptions.NoThrow property was set. The standard output and standard error output from the command. This is accumulated in real time so it can vary if the process is still running. This property is NOT available if the CommandOptions.OutputFile or CommandOptions.OutputStream is specified since the output is being redirected there. If a large amoutn of output is expected (> 1Meg), the Run.AddOutputStream(Stream) is recommended for retrieving it since the large string is never materialized at one time. Returns that CommandOptions structure that holds all the options that affect the running of the command (like Timeout, Input ...) Run 'commandLine', sending the output to the console, and wait for the command to complete. This simulates what batch filedo when executing their commands. It is a bit more verbose by default, however The command lineNumber to run as a subprocess Additional qualifiers that control how the process is run A Command structure that can be queried to determine ExitCode, Output, etc. Run 'commandLine' as a subprocess and waits for the command to complete. Output is captured and placed in the 'Output' property of the returned Command structure. The command lineNumber to run as a subprocess Additional qualifiers that control how the process is run A Command structure that can be queried to determine ExitCode, Output, etc. Launch a new command and returns the Command object that can be used to monitor the restult. It does not wait for the command to complete, however you can call 'Wait' to do that, or use the 'Run' or 'RunToConsole' methods. */ The command lineNumber to run as a subprocess Additional qualifiers that control how the process is run A Command structure that can be queried to determine ExitCode, Output, etc. Create a subprocess to run 'commandLine' with no special options. The command lineNumber to run as a subprocess Wait for a started process to complete (HasExited will be true on return) Wait returns that 'this' pointer. Throw a error if the command exited with a non-zero exit code printing useful diagnostic information along with the thrown message. This is useful when NoThrow is specified, and after post-processing you determine that the command really did fail, and an normal Command.Run failure was the appropriate action. An additional message to print in the throw (can be null) Get the underlying process object. Generally not used. Kill the process (and any child processses (recursively) associated with the running command). Note that it may not be able to kill everything it should if the child-parent' chain is broken by a child that creates a subprocess and then dies itself. This is reasonably uncommon, however. Kill the process (and any child processses (recursively) associated with the running command). Note that it may not be able to kill everything it should if the child-parent' chain is broken by a child that creates a subprocess and then dies itself. This is reasonably uncommon, however. #Overview The code:CommandLineParser is a utility for parsing command lines. Command lines consist of three basic entities. A command can have any (or none) of the following (separated by whitespace of any size). * PARAMETERS - this are non-space strings. They are positional (logicaly they are numbered). Strings with space can be specified by enclosing in double quotes. * QUALIFERS - Qualifiers are name-value pairs. The following syntax is supported. * -QUALIFER * -QUALIFER:VALUE * -QUALIFER=VALUE * -QUALIFER VALUE The end of a value is delimited by space. Again values with spaces can be encoded by enclosing them the value (or the whole qualifer-value string), in double quotes. The first form (where a value is not specified is only available for boolean qualifers, and boolean values can not use the form where the qualifer and value are separated by space. The '/' character can also be used instead of the '-' to begin a qualifier. Unlike parameters, qualifers are NOT ordered. They may occur in any order with respect to the parameters or other qualifers and THAT ORDER IS NOT COMMUNICATED THROUGH THE PARSER. Thus it is not possible to have qualifers that only apply to specific parameters. * PARAMETER SET SPECIFIER - A parameter set is optional argument that looks like a boolean qualifier (however if NoDashOnParameterSets is set the dash is not need, so it is looks like a parameter), that is special in that it decides what qualifers and positional parameters are allowed. See code:#ParameterSets for more #ParameterSets Parameter sets are an OPTIONAL facility of code:CommandLineParser that allow more complex command lines to be specified accurately. It not uncommon for a EXE to have several 'commands' that are logically independent of one another. For example a for example For example a program might have 'checkin' 'checkout' 'list' commands, and each of these commands has a different set of parameters that are needed and qualifers that are allowed. (for example checkout will take a list of file names, list needs nothing, and checkin needs a comment). Additionally some qualifers (like say -dataBaseName can apply to any of hte commands). Thus You would like to say that the following command lines are legal * EXE -checkout MyFile1 MyFile -dataBaseName:MyDatabase * EXE -dataBaseName:MyDatabase -list * EXE -comment "Specifying the comment first" -checkin * EXE -checkin -comment "Specifying the comment afterward" But the following are not * EXE -checkout * EXE -checkout -comment "hello" * EXE -list MyFile You do this by specifying 'checkout', 'list' and 'checkin' as paramters sets. On the command line they look like boolean qualifers, however they have additional sematantics. They must come before any positional parameters (because they affect whether the parameters are allowed and what they are named), and they are mutually exclusive. Each parameter set gets its own set of parameter definitions, and qualifilers can either be associated with a particular parameter set (like -comment) or global to all parameter sets (like -dataBaseName) . By default parameter set specifiers look like a boolean specifier (begin with a '-' or '/'), however because it is common practice to NOT have a dash for commands, there there is a Property code:CommandLineParser.NoDashOnParameterSets that indicates that the dash is not used. If this was specified then the following command would be legal. * EXE checkout MyFile1 MyFile -dataBaseName:MyDatabase #DefaultParameterSet One parameters set (which has the empty string name), is special in that it is used when no other parmeter set is matched. This is the default parameter set. For example, if -checkout was defined to be the default parameter set, then the following would be legal. * EXE Myfile1 Myfile And would implicitly mean 'checkout' Myfile1, Myfile2 If no parameter sets are defined, then all qualifiers and paramters are in the default parameter set. ------------------------------------------------------------------------- #Syntatic ambiguities Because whitespace can separate a qualifier from its value AND Qualifier from each other, and because parameter values might start with a dash (and thus look like qualifers), the syntax is ambiguous. It is disambigutated with the following rules. * The command line is parsed into 'arguments' that are spearated by whitespace. Any string enclosed in "" will be a single argument even if it has embedded whitespace. Double quote characters can be specified by \" (and a \" literal can be specified by \\" etc). * Arguments are parsed into qualifiers. This parsing stops if a '--' argument is found. Thus all qualifers must come before any '--' argument but parameters that begin with - can be specified by placing them after the '--' argument, * Qualifers are parsed. Because spaces can be used to separate a qualifer from its value, the type of the qualifer must be known to parse it. Boolean values never consume an additional parameter, and non-boolean qualifiers ALWAYS consume the next argument (if there is no : or =). If the empty string is to be specified, it must use the ':' or '=' form. Moreover it is illegal for the values that begin with '-' to use space as a separator. They must instead use the ':' or '=' form. This is because it is too confusing for humans to parse (values look like qualifiers). * Parameters are parsed. Whatever arguments that were not used by qualifers are parameters. -------------------------------------------------------------------------------------------- #DefiningParametersAndQualifiers The following example shows the steps for defining the parameters and qualifers for the example. Note that the order is important. Qualifers that apply to all commands must be specified first, then each parameter set then finally the default parameter set. Most steps are optional. class CommandLineParserExample1 { enum Command { checkout, checkin, list }; static void Main() { string dataBaseName = "myDefaultDataBase"; string comment = ""; Command command = checkout; string[] fileNames = null; // Step 1 define the parser. CommandLineParser commandLineParser = new CommandLineParser(); // by default uses Environment.CommandLine // Step 2 (optional) define qualifiers that apply to all parameter sets. commandLineParser.DefineOptionalParameter("dataBaseName", ref dataBaseName, "Help for database."); // Step 3A define the checkin command this includes all parameters and qualifers specific to this command commandLineParser.DefineParameterSet("checkin", ref command, Command.checkin, "Help for checkin."); commandLineParser.DefineOptionalQualifers("comment", ref comment, "Help for -comment."); // Step 3B define the list command this includes all parameters and qualifers specific to this command commandLineParser.DefineParameterSet("list", ref command, Command.list, "Help for list."); // Step 4 (optional) define the default parameter set (in this case checkout). commandLineParser.DefineDefaultParameterSet("checkout", ref command, Command.checkout, "Help for checkout."); commandLineParser.DefineParamter("fileNames", ref fileNames, "Help for fileNames."); // Step 5, do final validation (look for undefined qualifiers, extra parameters ... commandLineParser.CompleteValidation(); // Step 6 use the parsed values Console.WriteLine("Got {0} {1} {2} {3} {4}", dataBaseName, command, comment, string.Join(',', fileNames)); } } #RequiredAndOptional Parameters and qualifiers can be specified as required (the default), or optional. Makeing the default required was choses to make any mistakes 'obvious' since the parser will fail if a required parameter is not present (if the default was optional, it would be easy to make what should have been a required qualifer optional, leading to business logic failiure). #ParsedValues The class was designed maximize programmer convinience. For each parameter, only one call is needed to both define the parameter, its help message, and retrive its (strong typed) value. For example * int count = 5; * parser.DefineOptionalQualifer("count", ref count, "help for optional debugs qualifer"); Defines a qualifer 'count' and will place its value in the local variable 'count' as a integer. Default values are supported by doing nothing, so in the example above the default value will be 5. Types supported: The parser will support any type that has a static method called 'Parse' taking one string argument and returning that type. This is true for all primtive types, DateTime, Enumerations, and any user defined type that follows this convention. Array types: The parser has special knowedge of arrays. If the type of a qualifer is an array, then the string value is assumed to be a ',' separated list of strings which will be parsed as the element type of the array. In addition to the ',' syntax, it is also legal to specify the qualifer more than once. For example given the defintion * int[] counts; * parser.DefineOptionalQualifer("counts", ref counts, "help for optional counts qualifier"); The command line * EXE -counts 5 SomeArg -counts 6 -counts:7 Is the same as * EXE -counts:5,6,7 SomeArg If a qualifier or parameter is an array type and is required, then the array must have at least one element. If it is optional, then the array can be empty (but in all cases, the array is created, thus null is never returned by the command line parser). By default is it is illegal for a non-array qualifer to be specified more than once. It is however possible to override this behavior by setting the LastQualiferWins property before defining the qualifer. ------------------------------------------------------------------------- #Misc Qualifier can have more than one string form (typically a long and a short form). These are specified with the code:DefineAliases method. After defining all the qualifers and parameters, it is necessary to call the parser to check for the user specifying a qualifer (or parameter) that does not exist. This is the purpose of the code:CompleteValidation method. When an error is detected at runtime an instance of code:CommandLineParserException is thrown. The error message in this exception was designed to be suitable to print to the user directly. #CommandLineHelp The parser also can generate help that is correct for the qualifer and parameter definitions. This can be accessed from the code:CommandLineParser.GetHelp method. It is also possible to get the help for just a particular Parameter set with code:CommandLineParser.GetHelpForParameterSet. This help includes command line syntax, whether the qualifer or parameter is optional or a list, the types of the qualifers and parameters, the help text, and default values. The help text comes from the 'Define' Methods, and is properly word-wrapped. Newlines in the help text indicate new paragraphs. #AutomaticExceptionProcessingAndHelp In the CommandLineParserExample1, while the command line parser did a lot of the work there is still work needed to make the application user friendly that pretty much all applications need. These include * Call the code:CommandLineParser constructor and code:CommandLineParser.CompleteValidation * Catch any code:CommandLineParserException and print a friendly message * Define a -? qualifer and wire it up to print the help. Since this is stuff that all applications will likely need the code:CommandLineParser.ParseForConsoleApplication was created to do all of this for you, thus making it super-easy to make a production quality parser (and concentrate on getting your application logic instead of command line parsing. Here is an example which defines a 'Ping' command. If you will notice there are very few lines of code that are not expressing something very specific to this applications. This is how it should be! class CommandLineParserExample2 { static void Main() { CommandLineParser.ParseForConsoleApplication(delegate(CommandLineParser commandLineParser) { // Step 1: Initialize to the defaults string Host = null; int Timeout = 1000; bool Forever = false; // Step 2: Define the paramters, in this case there is only the default parameter set. CommandLineParser.ParseForConsoleApplication(args, delegate(CommandLineParser parser) { parser.DefineOptionalQualifier("Timeout", ref Timeout, "Timeout in milliseconds to wait for each reply."); parser.DefineOptionalQualifier("Forever", ref Forever, "Ping forever."); parser.DefineDefaultParameterSet("Ping sends a network request to a host to reply to the message (to check for liveness)."); parser.DefineParameter("Host", ref Host, "The Host to send a ping message to."); }); // Step 3, use the parameters Console.WriteLine("Got {0} {1} {2} {3}", Host, Timeout, Forever); }); } } Using local variables for the parsed arguments if fine when the program is not complex and the values don't need to be passed around to many routines. In general, however it is often a better idea to create a class whose sole purpose is to act as a repository for the parsed arguments. This also nicely separates all command line processing into a single class. This is how the ping example would look in that style. Notice that the main program no longer holds any command line processing logic. and that 'commandLine' can be passed to other routines in bulk easily. class CommandLineParserExample3 { static void Main() { CommandLine commandLine = new CommandLine(); Console.WriteLine("Got {0} {1} {2} {3}", commandLine.Host, commandLine.Timeout, commandLine.Forever); } } class CommandLine { public CommandLine() { CommandLineParser.ParseForConsoleApplication(args, delegate(CommandLineParser parser) { parser.DefineOptionalQualifier("Timeout", ref Timeout, "Timeout in milliseconds to wait for each reply."); parser.DefineOptionalQualifier("Forever", ref Forever, "Ping forever."); parser.DefineDefaultParameterSet("Ping sends a network request to a host to reply to the message (to check for liveness)."); parser.DefineParameter("Host", ref Host, "The Host to send a ping message to."); }); } public string Host = null; public int Timeout = 1000; public bool Forever = false; }; see code:#Overview for more If you are building a console Application, there is a common structure to parsing arguments. You want the text formated and output for console windows, and you want /? to be wired up to do this. All errors should be caught and displayed in a nice way. parseBody is the body of the parsing that this outer shell does not provide. in this delegate, you should be defining all the command line parameters using calls to Define* methods. Qualifiers are command line parameters of the form -NAME:VALUE where NAME is an alphanumeric name and VALUE is a string. The parser also accepts -NAME: VALUE and -NAME VALUE but not -NAME : VALUE For boolan parameters, the VALUE can be dropped (which means true), and a empty string VALUE means false. Thus -NAME means the same as -NAME:true and -NAME: means the same as -NAME:false (and boolean qualifiers DONT allow -NAME true or -NAME false). The types that are supported are any type that has a static 'Parse' function that takes a string (this includes all primitive types as well as DateTime, and Enumerations, as well as arrays of parsable types (values are comma separated without space). See code:#DefiningParametersAndQualifiers See code:#Overview Text to print for this qualifer. It will be word-wrapped. Newlines indicate new paragraphs. Like code:DeclareOptionalQualifier except it is an error if this parameter is not on the command line. Text to print for this qualifer. It will be word-wrapped. Newlines indicate new paragraphs. DefineParameter declares an unnamed parameter (basically any parameter that is not a qualifier). These are given ordinal numbers (starting at 0). You should declare the parameter in the desired order. See code:#DefiningParametersAndQualifiers See code:#Overview Text to print for this qualifer. It will be word-wrapped. Newlines indicate new paragraphs. Like code:DeclareParameter except it is an error if this parameter is not on the command line. These must come after non-optional (required) parameters. Text to print for this qualifer. It will be word-wrapped. Newlines indicate new paragraphs. A parameter set defines on of a set of 'commands' that decides how to parse the rest of the command line. If this 'command' is present on the command line then 'val' is assigned to 'retVal'. Typically 'retVal' is a variable of a enumerated type (one for each command), and 'val' is one specific value of that enumeration. * See code:#ParameterSets * See code:#DefiningParametersAndQualifiers * See code:#Overview Text to print for this qualifer. It will be word-wrapped. Newlines indicate new paragraphs. There is one special parameter set called the default parameter set (whose names is empty) which is used when a command line does not have one of defined parameter sets. It is always present, even if this method is not called, so alling this method is optional, however, by calling this method you can add help text for this case. If present this call must be AFTER all other parameter set definitions. * See code:#DefaultParameterSet * See code:#DefiningParametersAndQualifiers * See code:#Overview Text to print for this qualifer. It will be word-wrapped. Newlines indicate new paragraphs. This variation of DefineDefaultParameterSet has a 'retVal' and 'val' parameters. If the command line does not match any of the other parameter set defintions, then 'val' is asigned to 'retVal'. Typically 'retVal' is a variable of a enumerated type and 'val' is a value of that type. * See code:DefineDefaultParameterSet for more. Text to print for this qualifer. It will be word-wrapped. Newlines indicate new paragraphs. Specify additional aliases for an named parameter. This call must come BEFORE the definition, since the defintion is the operation that causes the parsing to happen. By default parameter set specifiers must look like a qualifer (begin with a -), however setting code:NoDashOnParameterSets will define a parameter set marker not to have any special prefix (just the name itself. If the positional parameters might look like named parameters (typically happens when the tail of the command line is literal text), it is useful to stop the search for named parameters at the first positional parameter. This property enables this behavior for the current parameter set. By default qualifers may being with a - or a / character. Setting code:QualifiersUseOnlyDash will make / invalid qualifer marker (only - can be used) By default, a non-list qualifier can not be specified more than once (since one or the other will have to be ignored. Normally an error is thrown. Setting code:LastQualiferWins makes it legal, and the last qualifer is the one that is used. Check for any paramters that the user specified but that were not defined by a Define*Parameter call and throw an exception if any are found. Return a string giving the help for the command, word wrapped at 'maxLineWidth' Return the string representing the help for a single paramter set. If displayGlobalQualifiers is true than qualifers that apply to all parameter sets is also included, otheriwse it is just the parameters and qualifers that are specific to that parameters set. Find the locations of all arguments that look like named parameters. Run time parsing error throw this exception. These are expected to be caught and the error message printed out to the user. Thus the messages should be 'user friendly'. This exception represents a compile time error in the command line parsing. These should not happen in correctly written programs. Given a list of arguments, from 'startAt' to the end of 'arguments' quote any arguments that have spaces in them so that the resulting command lineNumber has been turned back into a string that could be passed to a subprocess. The command lineNumber arguments parsed as space sparated token. The index in 'arguments' of the sub-array of interest (typically 0). A string that represents the original commannd lineNumber string before being parsed into array of space separated arguments General purpose utilities dealing with archiveFile system directories. SafeCopy sourceDirectory to directoryToVersion recursively. The target directory does no need to exist SafeCopy all files from sourceDirectory to directoryToVersion. If searchOptions == AllDirectories then the copy is recursive, otherwise it is just one level. The target directory does not need to exist. Clean is sort of a 'safe' recursive delete of a directory. It either deletes the files or moves them to '*.deleting' names. It deletes directories that are completely empty. Thus it will do a recursive delete when that is possible. There will only be *.deleting files after this returns. It returns the number of files and directories that could not be deleted. Removes the oldest directories directly under 'directoryPath' so that only 'numberToKeep' are left. Directory to removed old files from. The number of files to keep. true if there were no errors deleting files DirectoryUtilities.GetFiles is basically the same as Directory.GetFiles however it returns IEnumerator, which means that it lazy. This is very important for large directory trees. A searchPattern can be specified (Windows wildcard conventions) that can be used to filter the set of archiveFile names returned. Suggested Usage foreach(string fileName in DirectoryUtilities.GetFiles("c:\", "*.txt")){ Console.WriteLine(fileName); } The base directory to enumerate A pattern to filter the names (windows filename wildcards * ?) Indicate if the search is recursive or not. The enumerator for all archiveFile names in the directory (recursively). General purpose utilities dealing with archiveFile system files. GetLines works much like File.ReadAllLines, however instead of returning a array of lines, it returns a IEnumerable so that the archiveFile is not read all at once. This allows 'foreach' syntax to be used on very large files. Suggested Usage foreach(string lineNumber in FileUtilities.GetLines("largeFile.txt")){ Console.WriteLine(lineNumber); } The base directory to enumerate. The enumerator for all lines in the archiveFile. Given archiveFile specifications possibly with wildcards in them return an enumerator that returns each expanded archiveFile name in turn. If searchOpt is AllDirectories it does a recursive match. Delete works much like File.Delete, except that it will succeed if the archiveFile does not exist, and will rename the archiveFile so that even if the archiveFile is locked the original archiveFile variable will be made available. It renames the archiveFile with a '[num].deleting'. These files might be left behind. It returns true if it was competely successful. If there is a *.deleting archiveFile left behind, it returns false. The variable of the archiveFile to delete Try to delete 'fileName' catching any exception. Returns true if successful. It will delete read-only files. SafeCopy sourceFile to destinationFile. If the destination exists used ForceDelete to get rid of it first. Moves sourceFile to destinationFile. If the destination exists used ForceDelete to get rid of it first. CopyStream simply copies 'fromStream' to 'toStream' Privides a quick HTML users guide. Displayes an the embeded HTML user's guide in a browser. true if successful. A trivial routine, but we want to share even trivial common code. This program generates C# code for manipulating ETW events given the event XML schema definition Counts the number of newlines in 'str' from 'startIndex' of length 'length' EventSourceFinder is a class that can find all the EventSources in a file and can The code:CommandLine class holds the parsed form of all the command line arguments. It is intialized by handing it the 'args' array for main, and it has a public field for each named argument (eg -debug). See code:#CommandLineDefinitions for the code that defines the arguments (and the help strings associated with them). See code:CommandLineParser for more on parser itself. Given an eventName, return a list of all events with that name. Warns if two events with the same name have different Ids, and retnames the event to be unique. This is the prefix for any class names. Users can override this, but by default it is the last component (components separated by -) of the provider name. Users can override this however. If set then it assumes that the generated class should be internal and not public. If true it will cause the generation of a 'state' class associated with the parser to hold information needed from one event to the next Once you have set all the properties you wish, you can actually geneate a TraceEventParser to a particular output file by calling this routine. Change convention from ETW_KEYWORD_SESSION" to Session Generate the *Template helper functions as well as the EnumerateTemplates operation. Emit the C# events that allow you to get callback Accumulate all the information needed to fetch a field by field name. Also compute the assert that we will use to confirm the payload length is good. Generate all the enumeration types needed by the class defintions. returns C# code that will generate 'guid' in an efficient way (initializing by string is inefficient). Find all the information needed to create a payload decode class for a template (including offsets of the fields) and returns it as a list of 'FieldInfo' structures. Returns a string representing the C# code that will fetch the property for any of the versions described by 'versions'. 'totalVersions' is the maximum number of versions that the event (not just the property) has. ensures that the name is a valid CSharp Identifier. Represents all the information needed to decode a specific version of a field of a event payload. Returns string representing code that returns a 'default' value (a value to return when the value does not exist in the payload. This is 0 for numeric values and null for string values. Returns a string representing the offset of whatever is directly after this field. This method is static so that it can be called on a null field, which is convenient in several places. This is the last component (- separted) of the provider name. It decides what your TraceParserGen is named All the information from the manifest file. We group events together by version during the processing.