public static void Main(string[] args) { ConsoleApplication.WriteBanner(); // Get and validate args OptionCollection programOptions = new OptionCollection(); programOptions.Add(new SwitchOption("?", "Show this help page.")); programOptions.Add(new StringOption("d", "The directory containing CHM input files " + @"(e.g., HHP file). For example, 'C:\DocProject\Output\Chm'. Default is the current " + "directory.")); programOptions.Add(new StringOption("l", "The language code ID in decimal. For example, " + "'1033'. Default is '1033' (for EN-US).")); ParseArgumentsResult options = programOptions.ParseArguments(args); if (options.Options["?"].IsPresent) { programOptions.WriteOptionSummary(Console.Error); } // Determine the working dir string chmDirectory; if (options.Options["d"].IsPresent) { chmDirectory = options.Options["d"].Value.ToString(); } else { chmDirectory = Environment.CurrentDirectory; } // Determine the desired language string lcid; if (options.Options["l"].IsPresent) { lcid = options.Options["l"].Value.ToString(); } else { lcid = "1033"; } // Ensure working dir exists if (!Directory.Exists(chmDirectory)) { Console.WriteLine("The specified directory '{0}' doesn't exist. Quitting.", chmDirectory); return; } // Convert unsupported high-order chars to ascii equivalents SubstituteAsciiEquivalents(chmDirectory, lcid); // No further work required for 1033 if (String.Equals(lcid, "1033")) { return; } // Convert unsupported chars to named entities SubstituteNamedEntities(chmDirectory); // Convert charset declarations from utf8 to proper ansi codepage value SubstituteCodepages(chmDirectory, lcid); // Convert char encodings from utf8 to ansi ConvertUtf8ToAnsi(chmDirectory, lcid); }
/// <summary> /// Main program entry point (MSBuild task) /// </summary> /// <param name="args">The command line arguments</param> /// <returns>Zero on success or one on failure</returns> public static int MainEntryPoint(string[] args) { int exitCode = 0; ConsoleApplication.WriteBanner(); #region Read command line arguments, and setup config // Specify options OptionCollection options = new OptionCollection { new SwitchOption("?", "Show this help page."), new StringOption("config", "Specify a configuration file.", "configFilePath") }; // Process options ParseArgumentsResult results = options.ParseArguments(args); // Process help option if (results.Options["?"].IsPresent) { Console.WriteLine("BuildAssembler [options] manifestFilename"); options.WriteOptionSummary(Console.Out); return(1); } // check for invalid options if (!results.Success) { results.WriteParseErrors(Console.Out); return(1); } // Check for manifest if (results.UnusedArguments.Count != 1) { Console.WriteLine("You must supply exactly one manifest file."); return(1); } string manifest = results.UnusedArguments[0]; // Load the configuration file XPathDocument configuration; try { if (results.Options["config"].IsPresent) { configuration = ConsoleApplication.GetConfigurationFile((string)results.Options["config"].Value); } else { configuration = ConsoleApplication.GetConfigurationFile(); } } catch (IOException e) { ConsoleApplication.WriteMessage(LogLevel.Error, "The specified configuration file could not " + "be loaded. The error message is: {0}", e.Message); return(1); } catch (XmlException e) { ConsoleApplication.WriteMessage(LogLevel.Error, "The specified configuration file is not " + "well-formed. The error message is: {0}", e.Message); return(1); } #endregion // Create a build assembler instance to do the work. Messages are logged to the console logger. BuildAssembler = new BuildAssemblerCore((lvl, msg) => ConsoleApplication.WriteMessage(lvl, msg)); try { // Execute it using the given configuration and manifest BuildAssembler.Execute(configuration, manifest); } catch (Exception ex) { // Ignore aggregate exceptions where the inner exception is OperationCanceledException. // These are the result of logging an error message. if (!(ex is AggregateException) || !(ex.InnerException is OperationCanceledException)) { System.Diagnostics.Debug.WriteLine(ex); ConsoleApplication.WriteMessage(LogLevel.Error, ex.GetExceptionMessage()); } exitCode = 1; } finally { BuildAssembler.Dispose(); } return(exitCode); }
// Methods public static int Main(string[] args) { XPathDocument document; ConsoleApplication.WriteBanner(); OptionCollection options = new OptionCollection { new SwitchOption("?", "Show this help page."), new StringOption("config", "Specify a configuration file.", "versionCatalog"), new StringOption("out", "Specify an output file containing version information.", "outputFile"), new BooleanOption("rip", "Specify whether to rip old APIs which are not supported by the " + "latest versions.") }; ParseArgumentsResult result = options.ParseArguments(args); if (result.Options["?"].IsPresent) { Console.WriteLine("VersionBuilder [options]"); options.WriteOptionSummary(Console.Out); return(0); } if (!result.Success) { result.WriteParseErrors(Console.Out); return(1); } if (result.UnusedArguments.Count != 0) { Console.WriteLine("No non-option arguments are supported."); return(1); } if (!result.Options["config"].IsPresent) { ConsoleApplication.WriteMessage(LogLevel.Error, "You must specify a version catalog file."); return(1); } bool rip = true; if (result.Options["rip"].IsPresent && !((bool)result.Options["rip"].Value)) { rip = false; } string uri = (string)result.Options["config"].Value; try { document = new XPathDocument(uri); } catch (IOException ioEx) { ConsoleApplication.WriteMessage(LogLevel.Error, String.Format(CultureInfo.CurrentCulture, "An error occurred while accessing the version catalog file '{0}'. The error message " + "is: {1}", uri, ioEx.Message)); return(1); } catch (XmlException xmlEx) { ConsoleApplication.WriteMessage(LogLevel.Error, String.Format(CultureInfo.CurrentCulture, "The version catalog file '{0}' is not well-formed. The error message is: {1}", uri, xmlEx.Message)); return(1); } XPathNavigator navigator = document.CreateNavigator().SelectSingleNode("versions"); XPathExpression expr = XPathExpression.Compile("string(ancestor::versions/@name)"); List <VersionInfo> allVersions = new List <VersionInfo>(); List <string> latestVersions = new List <string>(); foreach (XPathNavigator navigator2 in document.CreateNavigator().Select("versions//version[@file]")) { string group = (string)navigator2.Evaluate(expr); string attribute = navigator2.GetAttribute("name", String.Empty); if (string.IsNullOrEmpty(attribute)) { ConsoleApplication.WriteMessage(LogLevel.Error, "Every version element must have a name attribute."); } string name = navigator2.GetAttribute("file", String.Empty); if (String.IsNullOrEmpty(attribute)) { ConsoleApplication.WriteMessage(LogLevel.Error, "Every version element must have a file attribute."); } name = Environment.ExpandEnvironmentVariables(name); VersionInfo item = new VersionInfo(attribute, group, name); allVersions.Add(item); } string str5 = String.Empty; foreach (VersionInfo info2 in allVersions) { if (info2.Group != str5) { latestVersions.Add(info2.Name); str5 = info2.Group; } } if (Cancel) { ConsoleApplication.WriteMessage(LogLevel.Info, "VersionBuilder canceled"); return(1); } XmlReaderSettings settings = new XmlReaderSettings { IgnoreWhitespace = true }; XmlWriterSettings settings2 = new XmlWriterSettings { Indent = true }; Dictionary <string, List <KeyValuePair <string, string> > > versionIndex = new Dictionary <string, List <KeyValuePair <string, string> > >(); Dictionary <string, Dictionary <string, ElementInfo> > dictionary2 = new Dictionary <string, Dictionary <string, ElementInfo> >(); XPathExpression expression2 = XPathExpression.Compile("string(/api/@id)"); XPathExpression expression4 = XPathExpression.Compile("/api/elements/element"); XPathExpression expression = XPathExpression.Compile("/api/attributes/attribute[type[@api='T:System.ObsoleteAttribute']]"); XPathExpression extensionAttributeExpression = XPathExpression.Compile("/api/attributes/attribute[type[@api='T:System.Runtime.CompilerServices.ExtensionAttribute']]"); XPathExpression extensionFirstParameterExpression = XPathExpression.Compile("/api/parameters/parameter[1]/*"); XPathExpression specialization = XPathExpression.Compile("./specialization"); XPathExpression templates = XPathExpression.Compile("./template[boolean(@index) and starts-with(@api, 'M:')]"); XPathExpression skipFirstParam = XPathExpression.Compile("./parameter[position()>1]"); XPathExpression expression6 = XPathExpression.Compile("boolean(argument[type[@api='T:System.Boolean'] and value[.='True']])"); XPathExpression apiChild = XPathExpression.Compile("./api"); foreach (VersionInfo info3 in allVersions) { if (Cancel) { ConsoleApplication.WriteMessage(LogLevel.Info, "VersionBuilder canceled"); return(1); } ConsoleApplication.WriteMessage(LogLevel.Info, String.Format(CultureInfo.CurrentCulture, "Indexing version '{0}' using file '{1}'.", info3.Name, info3.File)); try { XmlReader reader = XmlReader.Create(info3.File, settings); try { reader.MoveToContent(); while (reader.Read()) { if ((reader.NodeType == XmlNodeType.Element) && (reader.LocalName == "api")) { string key = String.Empty; List <KeyValuePair <string, string> > list3 = null; string str7 = String.Empty; Dictionary <string, ElementInfo> dictionary3 = null; XmlReader reader2 = reader.ReadSubtree(); XPathNavigator navigator3 = new XPathDocument(reader2).CreateNavigator(); key = (string)navigator3.Evaluate(expression2); if (!versionIndex.TryGetValue(key, out list3)) { list3 = new List <KeyValuePair <string, string> >(); versionIndex.Add(key, list3); } if (!dictionary2.TryGetValue(key, out dictionary3)) { dictionary3 = new Dictionary <string, ElementInfo>(); dictionary2.Add(key, dictionary3); } foreach (XPathNavigator navigator4 in navigator3.Select(expression4)) { ElementInfo info4; string str8 = navigator4.GetAttribute("api", String.Empty); if (!dictionary3.TryGetValue(str8, out info4)) { XPathNavigator elementNode = null; if ((navigator4.SelectSingleNode("*") != null) || (navigator4.SelectChildren(XPathNodeType.Attribute).Count > 1)) { elementNode = navigator4; } info4 = new ElementInfo(info3.Group, info3.Name, elementNode); dictionary3.Add(str8, info4); continue; } if (!info4.Versions.ContainsKey(info3.Group)) { info4.Versions.Add(info3.Group, info3.Name); } } XPathNavigator navigator6 = navigator3.SelectSingleNode(expression); if (navigator6 != null) { str7 = ((bool)navigator6.Evaluate(expression6)) ? "error" : "warning"; } if (key.StartsWith("M:", StringComparison.Ordinal)) { // Only check for extension methods when this is actually a method in question var navigator7 = navigator3.SelectSingleNode(extensionAttributeExpression); if (navigator7 != null) { // Check first parameter var navigator8 = navigator3.SelectSingleNode(extensionFirstParameterExpression); if (navigator8 != null) { // Get type node var typeID = navigator8.GetAttribute("api", String.Empty); if (navigator8.LocalName == "type") { var specNode = navigator8.SelectSingleNode(specialization); if (specNode == null || specNode.SelectChildren(XPathNodeType.Element).Count == specNode.Select(templates).Count) { // Either non-generic type or all type parameters are from within this method Dictionary <String, XPathNavigator> extMethods; if (!extensionMethods.TryGetValue(typeID, out extMethods)) { extMethods = new Dictionary <String, XPathNavigator>(); extensionMethods.Add(typeID, extMethods); } if (!extMethods.ContainsKey(key)) { extMethods.Add(key, navigator3.SelectSingleNode(apiChild)); } } } else { // TODO extension methods for generic parameters... } } } } list3.Add(new KeyValuePair <string, string>(info3.Name, str7)); str7 = String.Empty; reader2.Close(); } } } finally { reader.Close(); } continue; } catch (IOException ioEx) { ConsoleApplication.WriteMessage(LogLevel.Error, String.Format(CultureInfo.CurrentCulture, "An error occurred while accessing the input file '{0}'. The error message is: {1}", info3.File, ioEx.Message)); return(1); } catch (XmlException xmlEx) { ConsoleApplication.WriteMessage(LogLevel.Error, String.Format(CultureInfo.CurrentCulture, "The input file '{0}' is not well-formed. The error message is: {1}", info3.File, xmlEx.Message)); return(1); } } if (rip) { RemoveOldApis(versionIndex, latestVersions); } ConsoleApplication.WriteMessage(LogLevel.Info, String.Format(CultureInfo.CurrentCulture, "Indexed {0} entities in {1} versions.", versionIndex.Count, allVersions.Count)); try { XmlWriter writer; if (result.Options["out"].IsPresent) { writer = XmlWriter.Create((string)result.Options["out"].Value, settings2); } else { writer = XmlWriter.Create(Console.Out, settings2); } try { writer.WriteStartDocument(); writer.WriteStartElement("reflection"); writer.WriteStartElement("assemblies"); Dictionary <string, object> dictionary4 = new Dictionary <string, object>(); foreach (VersionInfo info5 in allVersions) { if (Cancel) { ConsoleApplication.WriteMessage(LogLevel.Info, "VersionBuilder canceled"); return(1); } using (XmlReader reader3 = XmlReader.Create(info5.File, settings)) { reader3.MoveToContent(); while (reader3.Read()) { if ((reader3.NodeType == XmlNodeType.Element) && (reader3.LocalName == "assembly")) { string str9 = reader3.GetAttribute("name"); if (!dictionary4.ContainsKey(str9)) { XmlReader reader4 = reader3.ReadSubtree(); writer.WriteNode(reader4, false); reader4.Close(); dictionary4.Add(str9, null); } } } } } writer.WriteEndElement(); writer.WriteStartElement("apis"); var readElements = new HashSet <String>(); foreach (VersionInfo info6 in allVersions) { if (Cancel) { ConsoleApplication.WriteMessage(LogLevel.Info, "VersionBuilder canceled"); return(1); } XmlReader reader5 = XmlReader.Create(info6.File, settings); reader5.MoveToContent(); while (reader5.Read()) { if ((reader5.NodeType == XmlNodeType.Element) && (reader5.LocalName == "api")) { string str10 = reader5.GetAttribute("id"); if (versionIndex.ContainsKey(str10)) { List <KeyValuePair <string, string> > versions = versionIndex[str10]; KeyValuePair <string, string> pair = versions[0]; if (info6.Name == pair.Key) { writer.WriteStartElement("api"); writer.WriteAttributeString("id", str10); XmlReader reader6 = reader5.ReadSubtree(); reader6.MoveToContent(); reader6.ReadStartElement(); Dictionary <String, XPathNavigator> eElems; var hasExtensionMethods = extensionMethods.TryGetValue(str10, out eElems); if (hasExtensionMethods) { readElements.Clear(); readElements.UnionWith(extensionMethods[str10].Keys); } while (!reader6.EOF) { if ((reader6.NodeType == XmlNodeType.Element) && (reader6.LocalName == "elements")) { Dictionary <string, ElementInfo> dictionary5 = dictionary2[str10]; Dictionary <string, object> dictionary6 = new Dictionary <string, object>(); writer.WriteStartElement("elements"); XmlReader reader7 = reader6.ReadSubtree(); foreach (XPathNavigator navigator8 in new XPathDocument(reader7).CreateNavigator().Select("elements/element")) { string str11 = navigator8.GetAttribute("api", String.Empty); dictionary6[str11] = null; writer.WriteStartElement("element"); writer.WriteAttributeString("api", str11); if (hasExtensionMethods) { readElements.Remove(str11); } foreach (string str12 in dictionary5[str11].Versions.Keys) { writer.WriteAttributeString(str12, dictionary5[str11].Versions[str12]); } foreach (XPathNavigator navigator9 in navigator8.Select("@*")) { if (navigator9.LocalName != "api") { writer.WriteAttributeString(navigator9.LocalName, navigator9.Value); } } foreach (XPathNavigator navigator10 in navigator8.Select("*")) { writer.WriteNode(navigator10, false); } writer.WriteEndElement(); } reader7.Close(); if (dictionary6.Count != dictionary5.Count) { foreach (string str13 in dictionary5.Keys) { if (dictionary6.ContainsKey(str13) || (rip && !IsLatestElement(dictionary5[str13].Versions.Values, latestVersions))) { continue; } writer.WriteStartElement("element"); writer.WriteAttributeString("api", str13); if (hasExtensionMethods) { readElements.Remove(str13); } foreach (string str14 in dictionary5[str13].Versions.Keys) { writer.WriteAttributeString(str14, dictionary5[str13].Versions[str14]); } if (dictionary5[str13].ElementNode != null) { foreach (XPathNavigator navigator11 in dictionary5[str13].ElementNode.Select("@*")) { if (navigator11.LocalName != "api") { writer.WriteAttributeString(navigator11.LocalName, navigator11.Value); } } foreach (XPathNavigator navigator12 in dictionary5[str13].ElementNode.Select("*")) { writer.WriteNode(navigator12, false); } } writer.WriteEndElement(); } } if (hasExtensionMethods) { foreach (var eMethodID in readElements) { writer.WriteStartElement("element"); writer.WriteAttributeString("api", eMethodID); writer.WriteAttributeString("source", "extension"); foreach (XPathNavigator extMember in eElems[eMethodID].SelectChildren(XPathNodeType.Element)) { switch (extMember.LocalName) { case "apidata": writer.WriteStartElement("apidata"); foreach (XPathNavigator apidataAttr in extMember.Select("@*")) { writer.WriteAttributeString(apidataAttr.LocalName, apidataAttr.Value); } writer.WriteAttributeString("subsubgroup", "extension"); foreach (XPathNavigator child in extMember.SelectChildren(XPathNodeType.All & ~XPathNodeType.Attribute)) { writer.WriteNode(child, false); } writer.WriteEndElement(); break; case "parameters": var noParamsWritten = true; foreach (XPathNavigator eParam in extMember.Select(skipFirstParam)) { if (noParamsWritten) { writer.WriteStartElement("parameters"); noParamsWritten = false; } writer.WriteNode(eParam, false); } if (!noParamsWritten) { writer.WriteEndElement(); } break; case "memberdata": writer.WriteStartElement("memberdata"); foreach (XPathNavigator mDataAttr in extMember.Select("@*")) { if (mDataAttr.LocalName != "static") { writer.WriteAttributeString(mDataAttr.LocalName, mDataAttr.Value); } } foreach (XPathNavigator child in extMember.SelectChildren(XPathNodeType.All & ~XPathNodeType.Attribute)) { writer.WriteNode(child, false); } writer.WriteEndElement(); break; case "attributes": break; default: writer.WriteNode(extMember, false); break; } } writer.WriteEndElement(); } } writer.WriteEndElement(); reader6.Read(); } else if (reader6.NodeType == XmlNodeType.Element) { writer.WriteNode(reader6, false); } else { reader6.Read(); } } reader6.Close(); writer.WriteStartElement("versions"); foreach (XPathNavigator navigator13 in navigator.SelectChildren(XPathNodeType.Element)) { WriteVersionTree(versions, navigator13, writer); } writer.WriteEndElement(); writer.WriteEndElement(); } } } } reader5.Close(); } writer.WriteEndElement(); writer.WriteEndElement(); writer.WriteEndDocument(); } finally { writer.Close(); } } catch (IOException ioEx) { ConsoleApplication.WriteMessage(LogLevel.Error, "An error occurred while generating the " + "output file. The error message is: {0}", ioEx.Message); return(1); } return(0); }
/// <summary> /// Main program entry point (MSBuild task) /// </summary> /// <param name="args">Command line arguments</param> /// <returns>Zero on success or non-zero on failure</returns> public static int MainEntryPoint(string[] args) { ConsoleApplication.WriteBanner(); // Specify options OptionCollection options = new OptionCollection { new SwitchOption("?", "Show this help page."), new ListOption("xsl", "Specify one or more XSL transform files.", "xsltPath") { RequiredMessage = "Specify at least one XSL transform file" }, new ListOption("arg", "Specify arguments.", "name=value"), new StringOption("out", "Specify an output file. If unspecified, output goes to the " + "console.", "outputFilePath"), new SwitchOption("w", "Do not ignore insignificant whitespace. By default " + "insignificant whitespace is ignored.") }; // Process options ParseArgumentsResult results = options.ParseArguments(args); if (results.Options["?"].IsPresent) { Console.WriteLine("XslTransform [options] xml_file"); options.WriteOptionSummary(Console.Out); return(1); } // Check for invalid options if (!results.Success) { results.WriteParseErrors(Console.Out); return(1); } // Check for missing or extra input files if (results.UnusedArguments.Count != 1) { Console.WriteLine("Specify one input XML input file."); return(1); } // Set whitespace setting bool ignoreWhitespace = !results.Options["w"].IsPresent; // Load transforms string[] transformFiles = (string[])results.Options["xsl"].Value; XslCompiledTransform[] transforms = new XslCompiledTransform[transformFiles.Length]; for (int i = 0; i < transformFiles.Length; i++) { string transformFile = Environment.ExpandEnvironmentVariables(transformFiles[i]); transforms[i] = new XslCompiledTransform(); XsltSettings transformSettings = new XsltSettings(true, true); try { transforms[i].Load(transformFile, transformSettings, new XmlUrlResolver()); } catch (IOException e) { ConsoleApplication.WriteMessage(LogLevel.Error, "The transform file '{0}' could not be " + "loaded. The error is: {1}", transformFile, e.Message); return(1); } catch (UnauthorizedAccessException e) { ConsoleApplication.WriteMessage(LogLevel.Error, "The transform file '{0}' could not be " + "loaded. The error is: {1}", transformFile, e.Message); return(1); } catch (XsltException e) { if (e.InnerException != null) { ConsoleApplication.WriteMessage(LogLevel.Error, "The transformation file '{0}' is " + "not valid. The error is: {1}", transformFile, e.InnerException.Message); } else { ConsoleApplication.WriteMessage(LogLevel.Error, "The transformation file '{0}' is " + "not valid. The error is: {1}", transformFile, e.Message); } return(1); } catch (XmlException e) { ConsoleApplication.WriteMessage(LogLevel.Error, "The transform file '{0}' is not " + "well-formed. The error is: {1}", transformFile, e.Message); return(1); } } // Compose the arguments XsltArgumentList arguments = new XsltArgumentList(); if (results.Options["arg"].IsPresent) { string[] nameValueStrings = (string[])results.Options["arg"].Value; foreach (string nameValueString in nameValueStrings) { string[] nameValuePair = nameValueString.Split('='); if (nameValuePair.Length != 2) { continue; } arguments.AddParam(nameValuePair[0], String.Empty, nameValuePair[1]); } } string input = Environment.ExpandEnvironmentVariables(results.UnusedArguments[0]); // Prepare the reader XmlReaderSettings readerSettings = new XmlReaderSettings { IgnoreWhitespace = ignoreWhitespace, CloseInput = true }; // Do each transform for (int i = 0; i < transforms.Length; i++) { ConsoleApplication.WriteMessage(LogLevel.Info, "Applying XSL transformation '{0}'.", transformFiles[i]); // Get the transform XslCompiledTransform transform = transforms[i]; // Figure out where to put the output string output; if (i < transforms.Length - 1) { try { output = Path.GetTempFileName(); File.SetAttributes(output, FileAttributes.Temporary); } catch (IOException e) { ConsoleApplication.WriteMessage(LogLevel.Error, "An error occurred while attempting " + "to create a temporary file. The error message is: {0}", e.Message); return(1); } } else if (results.Options["out"].IsPresent) { output = Environment.ExpandEnvironmentVariables((string)results.Options["out"].Value); } else { output = null; } // Create a reader Stream readStream; try { readStream = File.Open(input, FileMode.Open, FileAccess.Read, FileShare.ReadWrite | FileShare.Delete); } catch (IOException e) { ConsoleApplication.WriteMessage(LogLevel.Error, "The input file '{0}' could not be " + "loaded. The error is: {1}", input, e.Message); return(1); } catch (UnauthorizedAccessException e) { ConsoleApplication.WriteMessage(LogLevel.Error, "The input file '{0}' could not be " + "loaded. The error is: {1}", input, e.Message); return(1); } using (XmlReader reader = XmlReader.Create(readStream, readerSettings)) { // Create a writer Stream outputStream; if (output == null) { outputStream = Console.OpenStandardOutput(); } else { try { outputStream = File.Open(output, FileMode.Create, FileAccess.Write, FileShare.Read | FileShare.Delete); } catch (IOException e) { ConsoleApplication.WriteMessage(LogLevel.Error, "The output file '{0}' could not " + "be created. The error is: {1}", output, e.Message); return(1); } catch (UnauthorizedAccessException e) { ConsoleApplication.WriteMessage(LogLevel.Error, "The output file '{0}' could not " + "be created. The error is: {1}", output, e.Message); return(1); } } // Transform the file using (XmlWriter writer = XmlWriter.Create(outputStream, transform.OutputSettings)) { try { transform.Transform(reader, arguments, writer); } catch (TargetInvocationException e) { // If performing the Add Filenames transform and using GUID naming, the MD5 hashing // algorithm can be blocked if the FIPS policy is enabled. In such cases, tell the // user to switch to Member Name or Hashed Member Name as the naming method. This is // rare and using the alternate naming method is easier than replacing the MD5 // hashing which would be a significant breaking change. Exception fipsEx = e; while (fipsEx != null) { if (fipsEx is InvalidOperationException && fipsEx.Message.IndexOf(" FIPS ", StringComparison.Ordinal) != -1) { break; } fipsEx = fipsEx.InnerException; } if (fipsEx == null) { throw; } ConsoleApplication.WriteMessage(LogLevel.Error, "The FIPS validated cryptographic " + "algorithms policy appears to be enabled. This prevents the MD5 hashing algorithm " + "from being used to generate GUID topic filenames. Change the project's Naming " + "Method property to either Member Name or Hashed Member Name which do not rely " + "on the MD5 hashing algorithm."); return(1); } catch (XsltException e) { ConsoleApplication.WriteMessage(LogLevel.Error, "An error occurred during the " + "transformation. The error message is: {0}", (e.InnerException == null) ? e.Message : e.InnerException.Message); return(1); } catch (XmlException e) { ConsoleApplication.WriteMessage(LogLevel.Error, "The input file '{0}' is not " + "well-formed. The error is: {1}", input, e.Message); return(1); } } // If not using the console, close the output file or we sometimes get "file in use" errors // if we're quick enough and the garbage collector hasn't taken care of it. if (output != null) { outputStream.Close(); } } // If the last input was a temp file, delete it if (i > 0) { try { File.Delete(input); } catch (IOException ioEx) { ConsoleApplication.WriteMessage(LogLevel.Warn, "The temporary file '{0}' could not " + "be deleted. The error message is: {1}", input, ioEx.Message); } catch (UnauthorizedAccessException uaEx) { // !EFW - Virus scanners can sometimes cause an unauthorized access exception too ConsoleApplication.WriteMessage(LogLevel.Warn, "The temporary file '{0}' could not " + "be deleted. The error message is: {1}", input, uaEx.Message); } } // The last output file is the next input file input = output; if (Canceled) { ConsoleApplication.WriteMessage(LogLevel.Error, "XslTransform task canceled"); break; } } return(Canceled ? 1 : 0); }
public static int Main(string[] args) { // specify options OptionCollection options = new OptionCollection(); options.Add(new SwitchOption("?", "Show this help page.")); options.Add(new ListOption("xsl", "Specify transform files.", "xsltPath")); options.Add(new ListOption("arg", "Specify arguments.", "name=value")); options.Add(new StringOption("out", "Specify an output file. If unspecified, output goes to the console.", "outputFilePath")); options.Add(new SwitchOption("w", "Do not ignore insignificant whitespace. By default insignificant whitespace is ignored.")); ConsoleApplication.WriteBanner(); // process options ParseArgumentsResult results = options.ParseArguments(args); if (results.Options["?"].IsPresent) { Console.WriteLine("XslTransformer xsl_file [xml_file] [options]"); options.WriteOptionSummary(Console.Out); return(0); } // check for invalid options if (!results.Success) { results.WriteParseErrors(Console.Out); return(1); } // check for missing or extra assembly directories if (results.UnusedArguments.Count != 1) { Console.WriteLine("Specify one input XML input file."); return(1); } if (!results.Options["xsl"].IsPresent) { Console.WriteLine("Specify at least one XSL transform file."); return(1); } // set whitespace setting bool ignoreWhitespace = !results.Options["w"].IsPresent; // Load transforms string[] transformFiles = (string[])results.Options["xsl"].Value; XslCompiledTransform[] transforms = new XslCompiledTransform[transformFiles.Length]; for (int i = 0; i < transformFiles.Length; i++) { string transformFile = Environment.ExpandEnvironmentVariables(transformFiles[i]); transforms[i] = new XslCompiledTransform(); XsltSettings transformSettings = new XsltSettings(true, true); try { transforms[i].Load(transformFile, transformSettings, new XmlUrlResolver()); } catch (IOException e) { ConsoleApplication.WriteMessage(LogLevel.Error, String.Format("The transform file '{0}' could not be loaded. The error is: {1}", transformFile, e.Message)); return(1); } catch (UnauthorizedAccessException e) { ConsoleApplication.WriteMessage(LogLevel.Error, String.Format("The transform file '{0}' could not be loaded. The error is: {1}", transformFile, e.Message)); return(1); } catch (XsltException e) { if (e.InnerException != null) { ConsoleApplication.WriteMessage(LogLevel.Error, String.Format("The transformation file '{0}' is not valid. The error is: {1}", transformFile, e.InnerException.Message)); } else { ConsoleApplication.WriteMessage(LogLevel.Error, String.Format("The transformation file '{0}' is not valid. The error is: {1}", transformFile, e.Message)); } return(1); } catch (XmlException e) { ConsoleApplication.WriteMessage(LogLevel.Error, String.Format("The transform file '{0}' is not well-formed. The error is: {1}", transformFile, e.Message)); return(1); } } // Compose the arguments XsltArgumentList arguments = new XsltArgumentList(); if (results.Options["arg"].IsPresent) { string[] nameValueStrings = (string[])results.Options["arg"].Value; foreach (string nameValueString in nameValueStrings) { string[] nameValuePair = nameValueString.Split('='); if (nameValuePair.Length != 2) { continue; } arguments.AddParam(nameValuePair[0], String.Empty, nameValuePair[1]); } } string input = Environment.ExpandEnvironmentVariables(results.UnusedArguments[0]); // prepare the reader XmlReaderSettings readerSettings = new XmlReaderSettings(); readerSettings.IgnoreWhitespace = ignoreWhitespace; // Do each transform for (int i = 0; i < transforms.Length; i++) { ConsoleApplication.WriteMessage(LogLevel.Info, String.Format("Applying XSL transformation '{0}'.", transformFiles[i])); // get the transform XslCompiledTransform transform = transforms[i]; // figure out where to put the output string output; if (i < (transforms.Length - 1)) { try { output = Path.GetTempFileName(); File.SetAttributes(output, FileAttributes.Temporary); } catch (IOException e) { ConsoleApplication.WriteMessage(LogLevel.Error, String.Format("An error occured while attempting to create a temporary file. The error message is: {0}", e.Message)); return(1); } } else { if (results.Options["out"].IsPresent) { output = Environment.ExpandEnvironmentVariables((string)results.Options["out"].Value); } else { output = null; } } // create a reader Stream readStream; try { readStream = File.Open(input, FileMode.Open, FileAccess.Read, FileShare.ReadWrite | FileShare.Delete); } catch (IOException e) { ConsoleApplication.WriteMessage(LogLevel.Error, String.Format("The input file '{0}' could not be loaded. The error is: {1}", input, e.Message)); return(1); } catch (UnauthorizedAccessException e) { ConsoleApplication.WriteMessage(LogLevel.Error, String.Format("The input file '{0}' could not be loaded. The error is: {1}", input, e.Message)); return(1); } using (XmlReader reader = XmlReader.Create(readStream, readerSettings)) { // create a writer Stream outputStream; if (output == null) { outputStream = Console.OpenStandardOutput(); } else { try { outputStream = File.Open(output, FileMode.Create, FileAccess.Write, FileShare.Read | FileShare.Delete); } catch (IOException e) { ConsoleApplication.WriteMessage(LogLevel.Error, String.Format("The output file '{0}' could not be loaded. The error is: {1}", output, e.Message)); return(1); } catch (UnauthorizedAccessException e) { ConsoleApplication.WriteMessage(LogLevel.Error, String.Format("The output file '{0}' could not be loaded. The error is: {1}", output, e.Message)); return(1); } } using (XmlWriter writer = XmlWriter.Create(outputStream, transform.OutputSettings)) { try { // do the deed transform.Transform(reader, arguments, writer); } catch (XsltException e) { ConsoleApplication.WriteMessage(LogLevel.Error, String.Format("An error occured during the transformation. The error message is: {0}", (e.InnerException == null) ? e.Message : e.InnerException.Message)); return(1); } catch (XmlException e) { ConsoleApplication.WriteMessage(LogLevel.Error, String.Format("The input file '{0}' is not well-formed. The error is: {1}", input, e.Message)); return(1); } } } // if the last input was a temp file, delete it if (i > 0) { // Console.WriteLine("deleting {0}", input); try { File.Delete(input); } catch (IOException e) { ConsoleApplication.WriteMessage(LogLevel.Warn, String.Format("The temporary file '{0}' could not be deleted. The error message is: {1}", input, e.Message)); } } // the last output file is the next input file input = output; } return(0); }
/// <summary> /// Main program entry point (MSBuild task) /// </summary> /// <param name="args">Command line arguments</param> /// <returns>Zero on success or non-zero on failure</returns> public static int MainEntryPoint(string[] args) { string path, version, framework = null, assemblyPath, typeName; // Write banner ConsoleApplication.WriteBanner(); // Specify options OptionCollection options = new OptionCollection { new SwitchOption("?", "Show this help page."), new StringOption("out", "Specify an output file. If unspecified, output goes to the console.", "outputFilePath"), new StringOption("config", "Specify a configuration file. If unspecified, MRefBuilder.config is used", "configFilePath"), new ListOption("dep", "Specify assemblies to load for dependencies.", "dependencyAssembly") }; // Process options ParseArgumentsResult results = options.ParseArguments(args); if (results.Options["?"].IsPresent) { Console.WriteLine("MRefBuilder [options] assemblies"); options.WriteOptionSummary(Console.Out); return(1); } // Check for invalid options if (!results.Success) { results.WriteParseErrors(Console.Out); return(1); } // Check for missing or extra assembly directories if (results.UnusedArguments.Count < 1) { Console.WriteLine("Specify at least one assembly to reflect."); return(1); } // Load the configuration file XPathDocument config; XPathNavigator configNav; string configDirectory = ComponentUtilities.ToolsFolder, configFile = Path.Combine(ComponentUtilities.ToolsFolder, "MRefBuilder.config"); if (results.Options["config"].IsPresent) { configFile = (string)results.Options["config"].Value; configDirectory = Path.GetDirectoryName(configFile); } try { config = new XPathDocument(configFile); configNav = config.CreateNavigator(); } catch (IOException e) { ConsoleApplication.WriteMessage(LogLevel.Error, "An error occurred while attempting to read " + "the configuration file '{0}'. The error message is: {1}", configFile, e.Message); return(1); } catch (UnauthorizedAccessException e) { ConsoleApplication.WriteMessage(LogLevel.Error, "An error occurred while attempting to read " + "the configuration file '{0}'. The error message is: {1}", configFile, e.Message); return(1); } catch (XmlException e) { ConsoleApplication.WriteMessage(LogLevel.Error, "The configuration file '{0}' is not " + "well-formed. The error message is: {1}", configFile, e.Message); return(1); } // Adjust the target platform var platformNode = configNav.SelectSingleNode("/configuration/dduetools/platform"); if (platformNode == null) { ConsoleApplication.WriteMessage(LogLevel.Error, "A platform element is required to define the " + "framework type and version to use."); return(1); } // !EFW - Use the framework definition file to load core framework assembly reference information version = platformNode.GetAttribute("version", String.Empty); framework = platformNode.GetAttribute("framework", String.Empty); // Get component locations used to find additional reflection data definition files List <string> componentFolders = new List <string>(); var locations = configNav.SelectSingleNode("/configuration/dduetools/componentLocations"); if (locations != null) { foreach (XPathNavigator folder in locations.Select("location/@folder")) { if (!String.IsNullOrWhiteSpace(folder.Value) && Directory.Exists(folder.Value)) { componentFolders.Add(folder.Value); } } } // Get the dependencies string[] dependencies = Array.Empty <string>(); if (results.Options["dep"].IsPresent) { dependencies = (string[])results.Options["dep"].Value; } if (!String.IsNullOrEmpty(framework) && !String.IsNullOrEmpty(version)) { var coreNames = new HashSet <string>(new[] { "netstandard", "mscorlib", "System.Runtime" }, StringComparer.OrdinalIgnoreCase); var coreFrameworkAssemblies = results.UnusedArguments.Concat(dependencies).Where(d => coreNames.Contains(Path.GetFileNameWithoutExtension(d))); TargetPlatform.SetFrameworkInformation(framework, version, componentFolders, coreFrameworkAssemblies); } else { ConsoleApplication.WriteMessage(LogLevel.Error, "Unknown target framework version '{0} {1}'.", framework, version); return(1); } // Create an API member namer ApiNamer namer; // Apply a different naming method to assemblies using these frameworks if (framework == PlatformType.DotNetCore || framework == PlatformType.DotNetPortable || framework == PlatformType.WindowsPhone || framework == PlatformType.WindowsPhoneApp) { namer = new WindowsStoreAndPhoneNamer(); } else { namer = new OrcasNamer(); } XPathNavigator namerNode = configNav.SelectSingleNode("/configuration/dduetools/namer"); if (namerNode != null) { assemblyPath = namerNode.GetAttribute("assembly", String.Empty); typeName = namerNode.GetAttribute("type", String.Empty); assemblyPath = Environment.ExpandEnvironmentVariables(assemblyPath); if (!Path.IsPathRooted(assemblyPath)) { assemblyPath = Path.Combine(configDirectory, assemblyPath); } try { Assembly assembly = Assembly.LoadFrom(assemblyPath); namer = (ApiNamer)assembly.CreateInstance(typeName); if (namer == null) { ConsoleApplication.WriteMessage(LogLevel.Error, "The type '{0}' was not found in the " + "component assembly '{1}'.", typeName, assemblyPath); return(1); } } catch (IOException e) { ConsoleApplication.WriteMessage(LogLevel.Error, "A file access error occurred while " + "attempting to load the component assembly '{0}'. The error message is: {1}", assemblyPath, e.Message); return(1); } catch (UnauthorizedAccessException e) { ConsoleApplication.WriteMessage(LogLevel.Error, "A file access error occurred while " + "attempting to load the component assembly '{0}'. The error message is: {1}", assemblyPath, e.Message); return(1); } catch (BadImageFormatException) { ConsoleApplication.WriteMessage(LogLevel.Error, "The component assembly '{0}' is not a " + "valid managed assembly.", assemblyPath); return(1); } catch (TypeLoadException) { ConsoleApplication.WriteMessage(LogLevel.Error, "The type '{0}' was not found in the " + "component assembly '{1}'.", typeName, assemblyPath); return(1); } catch (MissingMethodException) { ConsoleApplication.WriteMessage(LogLevel.Error, "No appropriate constructor exists for " + "the type'{0}' in the component assembly '{1}'.", typeName, assemblyPath); return(1); } catch (TargetInvocationException e) { ConsoleApplication.WriteMessage(LogLevel.Error, "An error occurred while initializing the " + "type '{0}' in the component assembly '{1}'. The error message and stack trace " + "follows: {2}", typeName, assemblyPath, e.InnerException); return(1); } catch (InvalidCastException) { ConsoleApplication.WriteMessage(LogLevel.Error, "The type '{0}' in the component assembly " + "'{1}' is not a component type.", typeName, assemblyPath); return(1); } } // Create a resolver AssemblyResolver resolver = new AssemblyResolver(); XPathNavigator resolverNode = configNav.SelectSingleNode("/configuration/dduetools/resolver"); if (resolverNode != null) { assemblyPath = resolverNode.GetAttribute("assembly", String.Empty); typeName = resolverNode.GetAttribute("type", String.Empty); assemblyPath = Environment.ExpandEnvironmentVariables(assemblyPath); if (!Path.IsPathRooted(assemblyPath)) { assemblyPath = Path.Combine(configDirectory, assemblyPath); } try { Assembly assembly = Assembly.LoadFrom(assemblyPath); resolver = (AssemblyResolver)assembly.CreateInstance(typeName, false, BindingFlags.Public | BindingFlags.Instance, null, new object[1] { resolverNode }, null, null); if (resolver == null) { ConsoleApplication.WriteMessage(LogLevel.Error, "The type '{0}' was not found in the " + "component assembly '{1}'.", typeName, assemblyPath); return(1); } } catch (IOException e) { ConsoleApplication.WriteMessage(LogLevel.Error, "A file access error occurred while " + "attempting to load the component assembly '{0}'. The error message is: {1}", assemblyPath, e.Message); return(1); } catch (UnauthorizedAccessException e) { ConsoleApplication.WriteMessage(LogLevel.Error, "A file access error occurred while " + "attempting to load the component assembly '{0}'. The error message is: {1}", assemblyPath, e.Message); return(1); } catch (BadImageFormatException) { ConsoleApplication.WriteMessage(LogLevel.Error, "The component assembly '{0}' is not a " + "valid managed assembly.", assemblyPath); return(1); } catch (TypeLoadException) { ConsoleApplication.WriteMessage(LogLevel.Error, "The type '{0}' was not found in the " + "component assembly '{1}'.", typeName, assemblyPath); return(1); } catch (MissingMethodException) { ConsoleApplication.WriteMessage(LogLevel.Error, "No appropriate constructor exists for " + "the type'{0}' in the component assembly '{1}'.", typeName, assemblyPath); return(1); } catch (TargetInvocationException e) { ConsoleApplication.WriteMessage(LogLevel.Error, "An error occurred while initializing the " + "type '{0}' in the component assembly '{1}'. The error message and stack trace " + "follows: {2}", typeName, assemblyPath, e.InnerException); return(1); } catch (InvalidCastException) { ConsoleApplication.WriteMessage(LogLevel.Error, "The type '{0}' in the component assembly " + "'{1}' is not a component type.", typeName, assemblyPath); return(1); } } resolver.UnresolvedAssemblyReference += UnresolvedAssemblyReferenceHandler; // Get a text writer for output TextWriter output = Console.Out; if (results.Options["out"].IsPresent) { string file = (string)results.Options["out"].Value; try { output = new StreamWriter(file, false, Encoding.UTF8); } catch (IOException e) { ConsoleApplication.WriteMessage(LogLevel.Error, "An error occurred while attempting to " + "create an output file. The error message is: {0}", e.Message); return(1); } catch (UnauthorizedAccessException e) { ConsoleApplication.WriteMessage(LogLevel.Error, "An error occurred while attempting to " + "create an output file. The error message is: {0}", e.Message); return(1); } } try { // Create a writer string sourceCodeBasePath = (string)configNav.Evaluate( "string(/configuration/dduetools/sourceContext/@basePath)"); bool warnOnMissingContext = false; if (!String.IsNullOrWhiteSpace(sourceCodeBasePath)) { warnOnMissingContext = (bool)configNav.Evaluate( "boolean(/configuration/dduetools/sourceContext[@warnOnMissingSourceContext='true'])"); } else { ConsoleApplication.WriteMessage(LogLevel.Info, "No source code context base path " + "specified. Source context information is unavailable."); } ApiVisitor = new ManagedReflectionWriter(output, namer, resolver, sourceCodeBasePath, warnOnMissingContext, new ApiFilter(configNav.SelectSingleNode("/configuration/dduetools"))); // Register add-ins to the builder XPathNodeIterator addinNodes = configNav.Select("/configuration/dduetools/addins/addin"); foreach (XPathNavigator addinNode in addinNodes) { assemblyPath = addinNode.GetAttribute("assembly", String.Empty); typeName = addinNode.GetAttribute("type", String.Empty); assemblyPath = Environment.ExpandEnvironmentVariables(assemblyPath); if (!Path.IsPathRooted(assemblyPath)) { assemblyPath = Path.Combine(configDirectory, assemblyPath); } try { Assembly assembly = Assembly.LoadFrom(assemblyPath); MRefBuilderAddIn addin = (MRefBuilderAddIn)assembly.CreateInstance(typeName, false, BindingFlags.Public | BindingFlags.Instance, null, new object[2] { ApiVisitor, addinNode }, null, null); if (addin == null) { ConsoleApplication.WriteMessage(LogLevel.Error, "The type '{0}' was not found in " + "the add-in assembly '{1}'.", typeName, assemblyPath); return(1); } } catch (IOException e) { ConsoleApplication.WriteMessage(LogLevel.Error, "A file access error occurred while " + "attempting to load the add-in assembly '{0}'. The error message is: {1}", assemblyPath, e.Message); return(1); } catch (BadImageFormatException) { ConsoleApplication.WriteMessage(LogLevel.Error, "The add-in assembly '{0}' is not a " + "valid managed assembly.", assemblyPath); return(1); } catch (TypeLoadException) { ConsoleApplication.WriteMessage(LogLevel.Error, "The type '{0}' was not found in the " + "add-in assembly '{1}'.", typeName, assemblyPath); return(1); } catch (MissingMethodException) { ConsoleApplication.WriteMessage(LogLevel.Error, "No appropriate constructor exists " + "for the type '{0}' in the add-in assembly '{1}'.", typeName, assemblyPath); return(1); } catch (TargetInvocationException e) { ConsoleApplication.WriteMessage(LogLevel.Error, "An error occurred while initializing " + "the type '{0}' in the add-in assembly '{1}'. The error message and stack trace " + "follows: {2}", typeName, assemblyPath, e.InnerException); return(1); } catch (InvalidCastException) { ConsoleApplication.WriteMessage(LogLevel.Error, "The type '{0}' in the add-in " + "assembly '{1}' is not an MRefBuilderAddIn type.", typeName, assemblyPath); return(1); } } // Load dependencies foreach (string dependency in dependencies) { try { // Expand environment variables path = Environment.ExpandEnvironmentVariables(dependency); // If x86 but it didn't exist, assume it's a 32-bit system and change the name if (path.IndexOf("%ProgramFiles(x86)%", StringComparison.Ordinal) != -1) { path = Environment.ExpandEnvironmentVariables(path.Replace("(x86)", String.Empty)); } ApiVisitor.LoadAccessoryAssemblies(path); } catch (IOException e) { ConsoleApplication.WriteMessage(LogLevel.Error, "An error occurred while loading " + "dependency assemblies. The error message is: {0}", e.Message); return(1); } } // Parse the assemblies foreach (string dllPath in results.UnusedArguments.OrderBy(d => d.IndexOf("System.Runtime.dll", StringComparison.OrdinalIgnoreCase) != -1 ? 0 : d.IndexOf("netstandard.dll", StringComparison.OrdinalIgnoreCase) != -1 ? 1 : d.IndexOf("mscorlib.dll", StringComparison.OrdinalIgnoreCase) != -1 ? 2 : 3)) { try { // Expand environment variables path = Environment.ExpandEnvironmentVariables(dllPath); // If x86 but it didn't exist, assume it's a 32-bit system and change the name if (path.IndexOf("%ProgramFiles(x86)%", StringComparison.Ordinal) != -1) { path = Environment.ExpandEnvironmentVariables(path.Replace("(x86)", String.Empty)); } ApiVisitor.LoadAssemblies(path); } catch (IOException e) { ConsoleApplication.WriteMessage(LogLevel.Error, "An error occurred while loading " + "assemblies for reflection. The error message is: {0}", e.Message); return(1); } } ConsoleApplication.WriteMessage(LogLevel.Info, "Loaded {0} assemblies for reflection and " + "{1} dependency assemblies.", ApiVisitor.Assemblies.Count(), ApiVisitor.AccessoryAssemblies.Count()); ApiVisitor.VisitApis(); if (ApiVisitor.Canceled) { ConsoleApplication.WriteMessage(LogLevel.Error, "MRefBuilder task canceled"); } else { ConsoleApplication.WriteMessage(LogLevel.Info, "Wrote information on {0} namespaces, " + "{1} types, and {2} members", ApiVisitor.NamespaceCount, ApiVisitor.TypeCount, ApiVisitor.MemberCount); } } finally { if (ApiVisitor != null) { ApiVisitor.Dispose(); } if (results.Options["out"].IsPresent) { output.Close(); } } return((ApiVisitor != null && ApiVisitor.Canceled) ? 2 : 0); }
// Methods public static int Main(string[] args) { XPathDocument document; ConsoleApplication.WriteBanner(); OptionCollection options = new OptionCollection { new SwitchOption("?", "Show this help page."), new StringOption("out", "Specify an output directory. If unspecified, output goes to the " + "current directory.", "outputDirectory") }; ParseArgumentsResult result = options.ParseArguments(args); if (result.Options["?"].IsPresent) { Console.WriteLine("SegregateByAssembly [options] reflectionDataFile"); options.WriteOptionSummary(Console.Out); return(0); } if (!result.Success) { result.WriteParseErrors(Console.Out); return(1); } if (result.UnusedArguments.Count != 1) { Console.WriteLine("Specify one reflection data file."); return(1); } string uri = Environment.ExpandEnvironmentVariables(result.UnusedArguments[0]); string outputPath = null; if (result.Options["out"].IsPresent) { outputPath = Environment.ExpandEnvironmentVariables((string)result.Options["out"].Value); } try { document = new XPathDocument(uri); } catch (IOException ioEx) { ConsoleApplication.WriteMessage(LogLevel.Error, String.Format(CultureInfo.CurrentCulture, "An error occurred while attempting to access the file '{0}'. The error message is: {1}", uri, ioEx.Message)); return(1); } catch (XmlException xmlEx) { ConsoleApplication.WriteMessage(LogLevel.Error, String.Format(CultureInfo.CurrentCulture, "The input file '{0}' is not well-formed. The error message is: {1}", uri, xmlEx.Message)); return(1); } Dictionary <string, XmlWriter> dictionary = new Dictionary <string, XmlWriter>(); try { XmlWriter writer; XPathNodeIterator iterator = document.CreateNavigator().Select(assemblyExpression); foreach (XPathNavigator navigator in iterator) { string key = (string)navigator.Evaluate(assemblyIdExpression); string filename = key + ".xml"; if (outputPath != null) { filename = Path.Combine(outputPath, filename); } try { writer = CreateAssemblyWriter(filename, navigator); dictionary.Add(key, writer); } catch (IOException ioEx) { ConsoleApplication.WriteMessage(LogLevel.Error, String.Format(CultureInfo.CurrentCulture, "An access error occurred while attempting to create the output file '{0}'. " + "The error message is: {1}", filename, ioEx.Message)); return(1); } } string namespaceFile = "Namespaces.xml"; if (outputPath != null) { namespaceFile = Path.Combine(outputPath, namespaceFile); } try { writer = CreateAssemblyWriter(namespaceFile, null); dictionary.Add(string.Empty, writer); } catch (IOException ioEx) { ConsoleApplication.WriteMessage(LogLevel.Error, String.Format(CultureInfo.CurrentCulture, "An access error occurred while attempting to create the output file '{0}'. The " + "error message is: {1}", namespaceFile, ioEx.Message)); return(1); } XPathNodeIterator apiIterator = document.CreateNavigator().Select(apiExpression); foreach (XPathNavigator navigator2 in apiIterator) { string apiAssembly = (string)navigator2.Evaluate(apiAssemblyExpression); writer = dictionary[apiAssembly]; navigator2.WriteSubtree(writer); } foreach (XmlWriter w in dictionary.Values) { w.WriteEndElement(); w.WriteEndElement(); w.WriteEndDocument(); } ConsoleApplication.WriteMessage(LogLevel.Info, String.Format(CultureInfo.CurrentCulture, "Wrote information on {0} APIs to {1} files.", apiIterator.Count, dictionary.Count)); } finally { foreach (XmlWriter writer in dictionary.Values) { writer.Close(); } } return(0); }
//===================================================================== /// <summary> /// Main program entry point /// </summary> /// <param name="args">Command line arguments</param> /// <returns>Zero on success or non-zero on failure</returns> public static int Main(string[] args) { ConsoleApplication.WriteBanner(); // Specify options OptionCollection options = new OptionCollection(); options.Add(new SwitchOption("?", "Show this help page.")); options.Add(new ListOption("xsl", "Specify one or more XSL transform files.", "xsltPath") { RequiredMessage = "Specify at least one XSL transform file" }); options.Add(new ListOption("arg", "Specify arguments.", "name=value")); options.Add(new StringOption("out", "Specify an output file. If unspecified, output goes to the " + "console.", "outputFilePath")); options.Add(new SwitchOption("w", "Do not ignore insignificant whitespace. By default " + "insignificant whitespace is ignored.")); // Process options ParseArgumentsResult results = options.ParseArguments(args); if (results.Options["?"].IsPresent) { Console.WriteLine("XslTransform [options] xml_file"); options.WriteOptionSummary(Console.Out); return(1); } // Check for invalid options if (!results.Success) { results.WriteParseErrors(Console.Out); return(1); } // Check for missing or extra input files if (results.UnusedArguments.Count != 1) { Console.WriteLine("Specify one input XML input file."); return(1); } // Set whitespace setting bool ignoreWhitespace = !results.Options["w"].IsPresent; // Load transforms string[] transformFiles = (string[])results.Options["xsl"].Value; XslCompiledTransform[] transforms = new XslCompiledTransform[transformFiles.Length]; for (int i = 0; i < transformFiles.Length; i++) { string transformFile = Environment.ExpandEnvironmentVariables(transformFiles[i]); transforms[i] = new XslCompiledTransform(); XsltSettings transformSettings = new XsltSettings(true, true); try { transforms[i].Load(transformFile, transformSettings, new XmlUrlResolver()); } catch (IOException e) { ConsoleApplication.WriteMessage(LogLevel.Error, "The transform file '{0}' could not be " + "loaded. The error is: {1}", transformFile, e.Message); return(1); } catch (UnauthorizedAccessException e) { ConsoleApplication.WriteMessage(LogLevel.Error, "The transform file '{0}' could not be " + "loaded. The error is: {1}", transformFile, e.Message); return(1); } catch (XsltException e) { if (e.InnerException != null) { ConsoleApplication.WriteMessage(LogLevel.Error, "The transformation file '{0}' is " + "not valid. The error is: {1}", transformFile, e.InnerException.Message); } else { ConsoleApplication.WriteMessage(LogLevel.Error, "The transformation file '{0}' is " + "not valid. The error is: {1}", transformFile, e.Message); } return(1); } catch (XmlException e) { ConsoleApplication.WriteMessage(LogLevel.Error, "The transform file '{0}' is not " + "well-formed. The error is: {1}", transformFile, e.Message); return(1); } } // Compose the arguments XsltArgumentList arguments = new XsltArgumentList(); if (results.Options["arg"].IsPresent) { string[] nameValueStrings = (string[])results.Options["arg"].Value; foreach (string nameValueString in nameValueStrings) { string[] nameValuePair = nameValueString.Split('='); if (nameValuePair.Length != 2) { continue; } arguments.AddParam(nameValuePair[0], String.Empty, nameValuePair[1]); } } string input = Environment.ExpandEnvironmentVariables(results.UnusedArguments[0]); // Prepare the reader XmlReaderSettings readerSettings = new XmlReaderSettings(); readerSettings.IgnoreWhitespace = ignoreWhitespace; readerSettings.CloseInput = true; // Do each transform for (int i = 0; i < transforms.Length; i++) { ConsoleApplication.WriteMessage(LogLevel.Info, "Applying XSL transformation '{0}'.", transformFiles[i]); // Get the transform XslCompiledTransform transform = transforms[i]; // Figure out where to put the output string output; if (i < transforms.Length - 1) { try { output = Path.GetTempFileName(); File.SetAttributes(output, FileAttributes.Temporary); } catch (IOException e) { ConsoleApplication.WriteMessage(LogLevel.Error, "An error occurred while attempting " + "to create a temporary file. The error message is: {0}", e.Message); return(1); } } else if (results.Options["out"].IsPresent) { output = Environment.ExpandEnvironmentVariables((string)results.Options["out"].Value); } else { output = null; } // Create a reader Stream readStream; try { readStream = File.Open(input, FileMode.Open, FileAccess.Read, FileShare.ReadWrite | FileShare.Delete); } catch (IOException e) { ConsoleApplication.WriteMessage(LogLevel.Error, "The input file '{0}' could not be " + "loaded. The error is: {1}", input, e.Message); return(1); } catch (UnauthorizedAccessException e) { ConsoleApplication.WriteMessage(LogLevel.Error, "The input file '{0}' could not be " + "loaded. The error is: {1}", input, e.Message); return(1); } using (XmlReader reader = XmlReader.Create(readStream, readerSettings)) { // Create a writer Stream outputStream; if (output == null) { outputStream = Console.OpenStandardOutput(); } else { try { outputStream = File.Open(output, FileMode.Create, FileAccess.Write, FileShare.Read | FileShare.Delete); } catch (IOException e) { ConsoleApplication.WriteMessage(LogLevel.Error, "The output file '{0}' could not " + "be created. The error is: {1}", output, e.Message); return(1); } catch (UnauthorizedAccessException e) { ConsoleApplication.WriteMessage(LogLevel.Error, "The output file '{0}' could not " + "be created. The error is: {1}", output, e.Message); return(1); } } // Transform the file using (XmlWriter writer = XmlWriter.Create(outputStream, transform.OutputSettings)) { try { transform.Transform(reader, arguments, writer); } catch (XsltException e) { ConsoleApplication.WriteMessage(LogLevel.Error, "An error occurred during the " + "transformation. The error message is: {0}", (e.InnerException == null) ? e.Message : e.InnerException.Message); return(1); } catch (XmlException e) { ConsoleApplication.WriteMessage(LogLevel.Error, "The input file '{0}' is not " + "well-formed. The error is: {1}", input, e.Message); return(1); } } // If not using the console, close the output file or we sometimes get "file in use" errors // if we're quick enough and the garbage collector hasn't taken care of it. if (output != null) { outputStream.Close(); } } // If the last input was a temp file, delete it if (i > 0) { try { File.Delete(input); } catch (IOException ioEx) { ConsoleApplication.WriteMessage(LogLevel.Warn, "The temporary file '{0}' could not " + "be deleted. The error message is: {1}", input, ioEx.Message); } catch (UnauthorizedAccessException uaEx) { // !EFW - Virus scanners can sometimes cause an unauthorized access exception too ConsoleApplication.WriteMessage(LogLevel.Warn, "The temporary file '{0}' could not " + "be deleted. The error message is: {1}", input, uaEx.Message); } } // The last output file is the next input file input = output; if (Canceled) { ConsoleApplication.WriteMessage(LogLevel.Error, "XslTransform task canceled"); break; } } return(Canceled ? 1 : 0); }
// Methods public static int Main(string[] args) { XmlWriter writer; string key; ConsoleApplication.WriteBanner(); OptionCollection options = new OptionCollection { new SwitchOption("?", "Show this help page."), new StringOption("out", "Specify an output file. If unspecified, output goes to the " + "console.", "outputFilePath"), new StringOption("name", "Specify a name for the project node. If a name is specified, a " + "root topic is created.", "projectName") }; ParseArgumentsResult result = options.ParseArguments(args); if (result.Options["?"].IsPresent) { Console.WriteLine("AggregateByNamespace reflection_files [options]"); options.WriteOptionSummary(Console.Out); return(0); } if (!result.Success) { result.WriteParseErrors(Console.Out); return(1); } if (result.UnusedArguments.Count == 0) { Console.WriteLine("Specify one or more reflection files for processing."); return(1); } Dictionary <string, List <string> > dictionary = new Dictionary <string, List <string> >(); int num = 0; foreach (string reflectionFilename in result.UnusedArguments) { string fullPath = Path.GetFullPath(Path.GetDirectoryName(reflectionFilename)); foreach (string str2 in Directory.EnumerateFiles(fullPath, Path.GetFileName(reflectionFilename))) { try { XPathDocument document = new XPathDocument(str2); num++; XPathNodeIterator iterator = document.CreateNavigator().Select(typesExpression); foreach (XPathNavigator navigator in iterator) { List <string> list; string item = (string)navigator.Evaluate(typeIdExpression); if (item.Length == 0) { Console.WriteLine("Moo"); } key = (string)navigator.Evaluate(namespaceIdExpression); if (key.Length == 0) { Console.WriteLine("foo"); } if (!dictionary.TryGetValue(key, out list)) { list = new List <string>(); dictionary.Add(key, list); } list.Add(item); } } catch (IOException ioEx) { ConsoleApplication.WriteMessage(LogLevel.Error, String.Format(CultureInfo.CurrentCulture, "An error occurred while reading the input file '{0}'. The error message follows: {1}", str2, ioEx.Message)); return(1); } catch (XmlException xmlEx) { ConsoleApplication.WriteMessage(LogLevel.Error, String.Format(CultureInfo.CurrentCulture, "The input file '{0}' is not well-formed. The error message follows: {1}", str2, xmlEx.Message)); return(1); } } } ConsoleApplication.WriteMessage(LogLevel.Info, String.Format(CultureInfo.CurrentCulture, "Parsed {0} files", num)); XmlWriterSettings settings = new XmlWriterSettings { Indent = true }; int num2 = 0, num3 = 0; if (result.Options["out"].IsPresent) { string outputFileName = (string)result.Options["out"].Value; try { writer = XmlWriter.Create(outputFileName, settings); } catch (IOException ioEx) { ConsoleApplication.WriteMessage(LogLevel.Error, String.Format(CultureInfo.CurrentCulture, "An error occurred while trying to create the output file. The error message is: {0}", ioEx.Message)); return(1); } } else { writer = XmlWriter.Create(Console.Out, settings); } try { writer.WriteStartDocument(); writer.WriteStartElement("reflection"); writer.WriteStartElement("apis"); foreach (KeyValuePair <string, List <string> > pair in dictionary) { num2++; key = pair.Key; List <string> list2 = pair.Value; string str6 = key.Substring(2); writer.WriteStartElement("api"); writer.WriteAttributeString("id", key); writer.WriteStartElement("apidata"); writer.WriteAttributeString("group", "namespace"); writer.WriteAttributeString("name", str6); writer.WriteEndElement(); writer.WriteStartElement("elements"); foreach (string str3 in list2) { num3++; writer.WriteStartElement("element"); writer.WriteAttributeString("api", str3); writer.WriteEndElement(); } writer.WriteEndElement(); writer.WriteEndElement(); } if (result.Options["name"].IsPresent) { string str7 = "R:" + ((string)result.Options["name"].Value); writer.WriteStartElement("api"); writer.WriteAttributeString("id", str7); writer.WriteStartElement("apidata"); writer.WriteAttributeString("group", "root"); writer.WriteAttributeString("pseudo", "true"); writer.WriteEndElement(); writer.WriteStartElement("elements"); foreach (string str4 in dictionary.Keys) { writer.WriteStartElement("element"); writer.WriteAttributeString("api", str4); writer.WriteEndElement(); } writer.WriteEndElement(); } writer.WriteEndElement(); writer.WriteEndElement(); writer.WriteEndDocument(); } finally { writer.Close(); } ConsoleApplication.WriteMessage(LogLevel.Info, String.Format(CultureInfo.CurrentCulture, "Wrote {0} namespaces containing {1} types.", num2, num3)); return(0); }
static int Main(string[] args) { ConsoleApplication.WriteBanner(); // get and validate args OptionCollection programOptions = new OptionCollection(); programOptions.Add(new SwitchOption("?", "Show this help page.")); programOptions.Add(new StringOption("out", "(String) Path to the file that the input files should be merged in to. Required.")); programOptions.Add(new StringOption("position", "(String) The name of the element or elements to which the input elements will be appended. Required.")); programOptions.Add(new StringOption("include", @"(String) An xpath expression indicating which elements from the source files should be introduced in to the output file. The default is '/'")); ParseArgumentsResult options = programOptions.ParseArguments(args); if (options.Options["?"].IsPresent || !options.Options["out"].IsPresent || !options.Options["position"].IsPresent) { programOptions.WriteOptionSummary(Console.Error); Console.WriteLine(); Console.WriteLine("file1 file2 ..."); Console.WriteLine("The input files to operate on."); return(0); } // ensure output file exists string outputPath = options.Options["out"].Value.ToString(); if (!File.Exists(outputPath)) { ConsoleApplication.WriteMessage(LogLevel.Error, "The specified output file, which the input files are to be merged in to, doesn't exist."); return(1); } // ensure a postition element name was passed if (String.IsNullOrEmpty(options.Options["position"].Value.ToString())) { ConsoleApplication.WriteMessage(LogLevel.Error, "No position element name was provided."); return(1); } string positionName = options.Options["position"].Value.ToString(); // validate xpaths ("include" switch) string xpath; if (options.Options["include"].IsPresent) { xpath = options.Options["include"].Value.ToString(); } else { xpath = @"/"; } XPathExpression includeExpression; try { includeExpression = XPathExpression.Compile(xpath); } catch (XPathException) { ConsoleApplication.WriteMessage(LogLevel.Error, "The xpath expression provided by the include switch, '" + xpath + "', is invalid."); return(1); } // get list of input files to operate on if (options.UnusedArguments.Count == 0) { ConsoleApplication.WriteMessage(LogLevel.Error, "No input files were provided."); return(1); } string[] inputFiles = new string[options.UnusedArguments.Count]; options.UnusedArguments.CopyTo(inputFiles, 0); // ensure all input files exist foreach (string path in inputFiles) { if (!File.Exists(path)) { ConsoleApplication.WriteMessage(LogLevel.Error, "Specified input file '" + path + "' doesn't exist."); return(1); } } // open the output file and move to the position XmlWriterSettings outputSettings = new XmlWriterSettings(); outputSettings.Indent = true; outputSettings.Encoding = Encoding.UTF8; using (XmlWriter output = XmlWriter.Create(outputPath + ".tmp", outputSettings)) { // start printing output doc string until the selected node is matched using (XmlReader source = XmlReader.Create(outputPath)) { while (!source.EOF) { source.Read(); switch (source.NodeType) { case XmlNodeType.Element: output.WriteStartElement(source.Prefix, source.LocalName, source.NamespaceURI); output.WriteAttributes(source, true); if (source.IsEmptyElement) { output.WriteEndElement(); } if (String.Equals(source.Name, positionName, StringComparison.OrdinalIgnoreCase)) { // start introducing the elements from the input files foreach (string path in inputFiles) { XPathDocument inputDoc = new XPathDocument(path); XPathNavigator inputNav = inputDoc.CreateNavigator(); XPathNodeIterator inputNodesIterator = inputNav.Select(includeExpression); while (inputNodesIterator.MoveNext()) { output.WriteNode(inputNodesIterator.Current, true); } } } break; case XmlNodeType.Text: output.WriteString(source.Value); break; case XmlNodeType.Whitespace: case XmlNodeType.SignificantWhitespace: output.WriteWhitespace(source.Value); break; case XmlNodeType.CDATA: output.WriteCData(source.Value); break; case XmlNodeType.EntityReference: output.WriteEntityRef(source.Name); break; case XmlNodeType.XmlDeclaration: case XmlNodeType.ProcessingInstruction: output.WriteProcessingInstruction(source.Name, source.Value); break; case XmlNodeType.DocumentType: output.WriteDocType(source.Name, source.GetAttribute("PUBLIC"), source.GetAttribute("SYSTEM"), source.Value); break; case XmlNodeType.Comment: output.WriteComment(source.Value); break; case XmlNodeType.EndElement: output.WriteFullEndElement(); break; } } } output.WriteEndDocument(); output.Close(); } File.Delete(outputPath); File.Move(outputPath + ".tmp", outputPath); return(0); // pau }
public static int Main(string[] args) { ConsoleApplication.WriteBanner(); OptionCollection options = new OptionCollection(); options.Add(new SwitchOption("?", "Show this help page.")); options.Add(new StringOption("html", "Specify a html directory.", "htmlDirectory")); options.Add(new StringOption("project", "Specify a project name.", "projectName")); options.Add(new StringOption("toc", "Specify a toc file.", "tocFile")); options.Add(new StringOption("lcid", "Specify a language id.If unspecified, 1033 is used.", "languageId")); options.Add(new StringOption("out", "Specify an output directory. If unspecified, Chm is used.", "outputDirectory")); options.Add(new BooleanOption("metadata", "Specify whether output metadata or not. Default value is false.")); options.Add(new StringOption("config", "Specify a configuration file. If unspecified, ChmBuilder.config is used", "configFilePath")); ParseArgumentsResult results = options.ParseArguments(args); if (results.Options["?"].IsPresent) { Console.WriteLine("ChmBuilder /html: /project: /toc: /out: /metadata:"); options.WriteOptionSummary(Console.Out); return(0); } ChmBuilderArgs cbArgs = new ChmBuilderArgs(); // check for invalid options if (!results.Success) { results.WriteParseErrors(Console.Out); return(1); } // check for missing or extra assembly directories if (results.UnusedArguments.Count != 0) { Console.WriteLine("No non-option arguments are supported."); return(1); } if (!results.Options["html"].IsPresent) { ConsoleApplication.WriteMessage(LogLevel.Error, "You must specify a html directory."); return(1); } cbArgs.htmlDirectory = (string)results.Options["html"].Value; if (!Directory.Exists(cbArgs.htmlDirectory)) { ConsoleApplication.WriteMessage(LogLevel.Error, String.Format("Direcotry: {0} not found.", cbArgs.htmlDirectory)); return(1); } if (!results.Options["project"].IsPresent) { ConsoleApplication.WriteMessage(LogLevel.Error, "You must specify a project name."); return(1); } cbArgs.projectName = (string)results.Options["project"].Value; if (results.Options["lcid"].IsPresent) { try { cbArgs.langid = Convert.ToInt32(results.Options["lcid"].Value); } catch { ConsoleApplication.WriteMessage(LogLevel.Error, String.Format("{0} is not a valid integer.", results.Options["lcid"].Value)); return(1); } } if (results.Options["toc"].IsPresent) { cbArgs.tocFile = (string)results.Options["toc"].Value; if (!File.Exists(cbArgs.tocFile)) { ConsoleApplication.WriteMessage(LogLevel.Error, String.Format("File: {0} not found.", cbArgs.tocFile)); return(1); } } if (!results.Options["out"].IsPresent) { cbArgs.outputDirectory = "Chm"; } else { cbArgs.outputDirectory = (string)results.Options["out"].Value; } if (!Directory.Exists(cbArgs.outputDirectory)) { Directory.CreateDirectory(cbArgs.outputDirectory); //ConsoleApplication.WriteMessage(LogLevel.Error, String.Format("Direcotry: {0} not found.", cbArgs.outputDirectory)); //return (1); } if (results.Options["metadata"].IsPresent && (bool)results.Options["metadata"].Value) { cbArgs.metadata = true; } if (results.Options["config"].IsPresent) { cbArgs.configFile = (string)results.Options["config"].Value; } if (!File.Exists(cbArgs.configFile)) { ConsoleApplication.WriteMessage(LogLevel.Error, String.Format("Config file: {0} not found.", cbArgs.configFile)); return(1); } try { ChmBuilder chmBuilder = new ChmBuilder(cbArgs); chmBuilder.Run(); } catch (Exception ex) { Console.WriteLine(ex.ToString()); return(1); } return(0); }
public static int Main(string[] args) { // write banner ConsoleApplication.WriteBanner(); // specify options OptionCollection options = new OptionCollection(); options.Add(new SwitchOption("?", "Show this help page.")); options.Add(new StringOption("out", "Specify an output file. If unspecified, output goes to the console.", "outputFilePath")); options.Add(new StringOption("config", "Specify a configuration file. If unspecified, MRefBuilder.config is used", "configFilePath")); options.Add(new ListOption("dep", "Speficy assemblies to load for dependencies.", "dependencyAssembly")); // options.Add( new BooleanOption("namespaces", "Control whether information on namespaces in provided.") ); options.Add(new BooleanOption("internal", "Specify whether to document internal as well as externally exposed APIs.")); // process options ParseArgumentsResult results = options.ParseArguments(args); if (results.Options["?"].IsPresent) { Console.WriteLine("MRefBuilder [options] assemblies"); options.WriteOptionSummary(Console.Out); return(0); } // check for invalid options if (!results.Success) { results.WriteParseErrors(Console.Out); return(1); } // check for missing or extra assembly directories if (results.UnusedArguments.Count < 1) { Console.WriteLine("Specify at least one assembly to reflect."); return(1); } // load the configuration file XPathDocument config; string configDirectory = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); string configFile = Path.Combine(configDirectory, "MRefBuilder.config"); if (results.Options["config"].IsPresent) { configFile = (string)results.Options["config"].Value; configDirectory = Path.GetDirectoryName(configFile); } try { config = new XPathDocument(configFile); } catch (IOException e) { ConsoleApplication.WriteMessage(LogLevel.Error, String.Format("An error occured while attempting to read the configuration file '{0}'. The error message is: {1}", configFile, e.Message)); return(1); } catch (UnauthorizedAccessException e) { ConsoleApplication.WriteMessage(LogLevel.Error, String.Format("An error occured while attempting to read the configuration file '{0}'. The error message is: {1}", configFile, e.Message)); return(1); } catch (XmlException e) { ConsoleApplication.WriteMessage(LogLevel.Error, String.Format("The configuration file '{0}' is not well-formed. The error message is: {1}", configFile, e.Message)); return(1); } // adjust the target platform XPathNodeIterator platformNodes = config.CreateNavigator().Select("/configuration/dduetools/platform"); if (platformNodes.MoveNext()) { XPathNavigator platformNode = platformNodes.Current; string version = platformNode.GetAttribute("version", String.Empty); string path = platformNode.GetAttribute("path", String.Empty); path = Environment.ExpandEnvironmentVariables(path); if (!Directory.Exists(path)) { ConsoleApplication.WriteMessage(LogLevel.Error, String.Format("The specifed target platform directory '{0}' does not exist.", path)); return(1); } if (version == "2.0") { TargetPlatform.SetToV2(path); } else if (version == "1.1") { TargetPlatform.SetToV1_1(path); } else if (version == "1.0") { TargetPlatform.SetToV1(path); } else { Console.WriteLine("Unknown target platform version '{0}'.", version); return(1); } } // create a namer ApiNamer namer = new OrcasNamer(); XPathNavigator namerNode = config.CreateNavigator().SelectSingleNode("/configuration/dduetools/namer"); if (namerNode != null) { string assemblyPath = namerNode.GetAttribute("assembly", String.Empty); string typeName = namerNode.GetAttribute("type", String.Empty); assemblyPath = Environment.ExpandEnvironmentVariables(assemblyPath); if (!Path.IsPathRooted(assemblyPath)) { assemblyPath = Path.Combine(configDirectory, assemblyPath); } try { Assembly assembly = Assembly.LoadFrom(assemblyPath); namer = (ApiNamer)assembly.CreateInstance(typeName); if (namer == null) { ConsoleApplication.WriteMessage(LogLevel.Error, String.Format("The type '{0}' was not found in the component assembly '{1}'.", typeName, assemblyPath)); return(1); } } catch (IOException e) { ConsoleApplication.WriteMessage(LogLevel.Error, String.Format("A file access error occured while attempting to load the component assembly '{0}'. The error message is: {1}", assemblyPath, e.Message)); return(1); } catch (UnauthorizedAccessException e) { ConsoleApplication.WriteMessage(LogLevel.Error, String.Format("A file access error occured while attempting to load the component assembly '{0}'. The error message is: {1}", assemblyPath, e.Message)); return(1); } catch (BadImageFormatException) { ConsoleApplication.WriteMessage(LogLevel.Error, String.Format("The component assembly '{0}' is not a valid managed assembly.", assemblyPath)); return(1); } catch (TypeLoadException) { ConsoleApplication.WriteMessage(LogLevel.Error, String.Format("The type '{0}' was not found in the component assembly '{1}'.", typeName, assemblyPath)); return(1); } catch (MissingMethodException) { ConsoleApplication.WriteMessage(LogLevel.Error, String.Format("No appropriate constructor exists for the type'{0}' in the component assembly '{1}'.", typeName, assemblyPath)); return(1); } catch (TargetInvocationException e) { ConsoleApplication.WriteMessage(LogLevel.Error, String.Format("An error occured while initializing the type '{0}' in the component assembly '{1}'. The error message and stack trace follows: {2}", typeName, assemblyPath, e.InnerException.ToString())); return(1); } catch (InvalidCastException) { ConsoleApplication.WriteMessage(LogLevel.Error, String.Format("The type '{0}' in the component assembly '{1}' is not a component type.", typeName, assemblyPath)); return(1); } } // create a resolver AssemblyResolver resolver = new AssemblyResolver(); XPathNavigator resolverNode = config.CreateNavigator().SelectSingleNode("/configuration/dduetools/resolver"); if (resolverNode != null) { string assemblyPath = resolverNode.GetAttribute("assembly", String.Empty); string typeName = resolverNode.GetAttribute("type", String.Empty); assemblyPath = Environment.ExpandEnvironmentVariables(assemblyPath); if (!Path.IsPathRooted(assemblyPath)) { assemblyPath = Path.Combine(configDirectory, assemblyPath); } try { Assembly assembly = Assembly.LoadFrom(assemblyPath); resolver = (AssemblyResolver)assembly.CreateInstance(typeName, false, BindingFlags.Public | BindingFlags.Instance, null, new Object[1] { resolverNode }, null, null); if (resolver == null) { ConsoleApplication.WriteMessage(LogLevel.Error, String.Format("The type '{0}' was not found in the component assembly '{1}'.", typeName, assemblyPath)); return(1); } } catch (IOException e) { ConsoleApplication.WriteMessage(LogLevel.Error, String.Format("A file access error occured while attempting to load the component assembly '{0}'. The error message is: {1}", assemblyPath, e.Message)); return(1); } catch (UnauthorizedAccessException e) { ConsoleApplication.WriteMessage(LogLevel.Error, String.Format("A file access error occured while attempting to load the component assembly '{0}'. The error message is: {1}", assemblyPath, e.Message)); return(1); } catch (BadImageFormatException) { ConsoleApplication.WriteMessage(LogLevel.Error, String.Format("The component assembly '{0}' is not a valid managed assembly.", assemblyPath)); return(1); } catch (TypeLoadException) { ConsoleApplication.WriteMessage(LogLevel.Error, String.Format("The type '{0}' was not found in the component assembly '{1}'.", typeName, assemblyPath)); return(1); } catch (MissingMethodException) { ConsoleApplication.WriteMessage(LogLevel.Error, String.Format("No appropriate constructor exists for the type'{0}' in the component assembly '{1}'.", typeName, assemblyPath)); return(1); } catch (TargetInvocationException e) { ConsoleApplication.WriteMessage(LogLevel.Error, String.Format("An error occured while initializing the type '{0}' in the component assembly '{1}'. The error message and stack trace follows: {2}", typeName, assemblyPath, e.InnerException.ToString())); return(1); } catch (InvalidCastException) { ConsoleApplication.WriteMessage(LogLevel.Error, String.Format("The type '{0}' in the component assembly '{1}' is not a component type.", typeName, assemblyPath)); return(1); } } resolver.UnresolvedAssemblyReference += new EventHandler <AssemblyReferenceEventArgs>(UnresolvedAssemblyReferenceHandler); // get a textwriter for output TextWriter output = Console.Out; if (results.Options["out"].IsPresent) { string file = (string)results.Options["out"].Value; try { output = new StreamWriter(file, false, Encoding.UTF8); } catch (IOException e) { ConsoleApplication.WriteMessage(LogLevel.Error, String.Format("An error occured while attempting to create an output file. The error message is: {0}", e.Message)); return(1); } catch (UnauthorizedAccessException e) { ConsoleApplication.WriteMessage(LogLevel.Error, String.Format("An error occured while attempting to create an output file. The error message is: {0}", e.Message)); return(1); } } // dependency directory string[] dependencies = new string[0]; if (results.Options["dep"].IsPresent) { dependencies = (string[])results.Options["dep"].Value; } try { // create a builder ManagedReflectionWriter builder = new ManagedReflectionWriter(output, namer); // specify the resolver for the builder builder.Resolver = resolver; // builder.ApiFilter = new ExternalDocumentedFilter(config.CreateNavigator().SelectSingleNode("/configuration/dduetools")); // specify the filter for the builder if (results.Options["internal"].IsPresent && (bool)results.Options["internal"].Value) { builder.ApiFilter = new AllDocumentedFilter(config.CreateNavigator().SelectSingleNode("/configuration/dduetools")); } else { builder.ApiFilter = new ExternalDocumentedFilter(config.CreateNavigator().SelectSingleNode("/configuration/dduetools")); } // register add-ins to the builder XPathNodeIterator addinNodes = config.CreateNavigator().Select("/configuration/dduetools/addins/addin"); foreach (XPathNavigator addinNode in addinNodes) { string assemblyPath = addinNode.GetAttribute("assembly", String.Empty); string typeName = addinNode.GetAttribute("type", String.Empty); assemblyPath = Environment.ExpandEnvironmentVariables(assemblyPath); if (!Path.IsPathRooted(assemblyPath)) { assemblyPath = Path.Combine(configDirectory, assemblyPath); } try { Assembly assembly = Assembly.LoadFrom(assemblyPath); MRefBuilderAddIn addin = (MRefBuilderAddIn)assembly.CreateInstance(typeName, false, BindingFlags.Public | BindingFlags.Instance, null, new Object[2] { builder, addinNode }, null, null); if (namer == null) { ConsoleApplication.WriteMessage(LogLevel.Error, String.Format("The type '{0}' was not found in the addin assembly '{1}'.", typeName, assemblyPath)); return(1); } } catch (IOException e) { ConsoleApplication.WriteMessage(LogLevel.Error, String.Format("A file access error occured while attempting to load the addin assembly '{0}'. The error message is: {1}", assemblyPath, e.Message)); return(1); } catch (BadImageFormatException) { ConsoleApplication.WriteMessage(LogLevel.Error, String.Format("The addin assembly '{0}' is not a valid managed assembly.", assemblyPath)); return(1); } catch (TypeLoadException) { ConsoleApplication.WriteMessage(LogLevel.Error, String.Format("The type '{0}' was not found in the addin assembly '{1}'.", typeName, assemblyPath)); return(1); } catch (MissingMethodException) { ConsoleApplication.WriteMessage(LogLevel.Error, String.Format("No appropriate constructor exists for the type '{0}' in the addin assembly '{1}'.", typeName, assemblyPath)); return(1); } catch (TargetInvocationException e) { ConsoleApplication.WriteMessage(LogLevel.Error, String.Format("An error occured while initializing the type '{0}' in the addin assembly '{1}'. The error message and stack trace follows: {2}", typeName, assemblyPath, e.InnerException.ToString())); return(1); } catch (InvalidCastException) { ConsoleApplication.WriteMessage(LogLevel.Error, String.Format("The type '{0}' in the addin assembly '{1}' is not an MRefBuilderAddIn type.", typeName, assemblyPath)); return(1); } } try { // add a handler for unresolved assembly references //builder.UnresolvedModuleHandler = new System.Compiler.Module.AssemblyReferenceResolver(AssemblyNotFound); // load dependent bits foreach (string dependency in dependencies) { try { builder.LoadAccessoryAssemblies(dependency); } catch (IOException e) { ConsoleApplication.WriteMessage(LogLevel.Error, String.Format("An error occured while loading dependency assemblies. The error message is: {0}", e.Message)); return(1); } } // parse the bits foreach (string dllPath in results.UnusedArguments) { try { builder.LoadAssemblies(dllPath); } catch (IOException e) { ConsoleApplication.WriteMessage(LogLevel.Error, String.Format("An error occured while loading assemblies for reflection. The error message is: {0}", e.Message)); return(1); } } ConsoleApplication.WriteMessage(LogLevel.Info, String.Format("Loaded {0} assemblies for reflection and {1} dependency assemblies.", builder.Assemblies.Length, builder.AccessoryAssemblies.Length)); // register callbacks //builder.RegisterStartTagCallback("apis", new MRefBuilderCallback(startTestCallback)); //MRefBuilderAddIn addin = new XamlAttachedMembersAddIn(builder, null); builder.VisitApis(); ConsoleApplication.WriteMessage(LogLevel.Info, String.Format("Wrote information on {0} namespaces, {1} types, and {2} members", builder.Namespaces.Length, builder.Types.Length, builder.Members.Length)); } finally { builder.Dispose(); } } finally { // output.Close(); } return(0); }
/// <summary> /// Main program entry point /// </summary> /// <param name="args">Command line arguments</param> /// <returns>Zero on success or non-zero on failure</returns> public static int MainEntryPoint(string[] args) { XPathDocument document; ConsoleApplication.WriteBanner(); OptionCollection options = new OptionCollection { new SwitchOption("?", "Show this help page."), new StringOption("out", "Specify an output directory. If not specified, output goes to the " + "current directory.", "outputDirectory") }; ParseArgumentsResult result = options.ParseArguments(args); if (result.Options["?"].IsPresent) { Console.WriteLine("SegregateByNamespace [options] reflectionDataFile"); options.WriteOptionSummary(Console.Out); return(1); } if (!result.Success) { result.WriteParseErrors(Console.Out); return(1); } if (result.UnusedArguments.Count != 1) { Console.WriteLine("Specify one reflection data file."); return(1); } string uri = Environment.ExpandEnvironmentVariables(result.UnusedArguments[0]); string outputPath = null; if (result.Options["out"].IsPresent) { outputPath = Environment.ExpandEnvironmentVariables((string)result.Options["out"].Value); if (!Directory.Exists(outputPath)) { Directory.CreateDirectory(outputPath); } } try { document = new XPathDocument(uri); } catch (IOException ioEx) { ConsoleApplication.WriteMessage(LogLevel.Error, String.Format(CultureInfo.CurrentCulture, "An error occurred while attempting to access the file '{0}'. The error message is: {1}", uri, ioEx.Message)); return(1); } catch (XmlException xmlEx) { ConsoleApplication.WriteMessage(LogLevel.Error, String.Format(CultureInfo.CurrentCulture, "An exception processing the input file '{0}'. The error message is: {1}", uri, xmlEx.Message)); return(1); } if (!Canceled) { WriteNamespaceFiles(document, outputPath); } return(Canceled ? 1 : 0); }
private bool ParseDirectInput(BuildLogger logger) { string arguments = this.Arguments; string application = this.Application; if (application == null || application.Length == 0 || arguments == null && arguments.Length == 0) { return(false); } // specify options OptionCollection options = new OptionCollection(); options.Add(new SwitchOption("?", "Show this help page.")); options.Add(new ListOption("xsl", "Specify transform files.", "xsltPath")); options.Add(new ListOption("arg", "Specify arguments.", "name=value")); options.Add(new StringOption("out", "Specify an output file. If unspecified, output goes to the console.", "outputFilePath")); options.Add(new SwitchOption("w", "Do not ignore insignificant whitespace. By default insignificant whitespace is ignored.")); // process options string[] commandArgs = ParseArgumentsResult.SplitCommandLineArgument(arguments); ParseArgumentsResult results = options.ParseArguments(commandArgs); if (results.Options["?"].IsPresent) { if (logger != null) { logger.WriteLine("XslTransformer xsl_file [xml_file] [options]", BuildLoggerLevel.Error); } options.WriteOptionSummary(Console.Out); return(false); } // check for invalid options if (!results.Success) { results.WriteParseErrors(Console.Out); return(false); } // check for missing or extra assembly directories if (results.UnusedArguments.Count != 1) { if (logger != null) { logger.WriteLine("Specify one input XML input file.", BuildLoggerLevel.Error); } return(false); } if (!results.Options["xsl"].IsPresent) { if (logger != null) { logger.WriteLine("Specify at least one XSL transform file.", BuildLoggerLevel.Error); } return(false); } // set whitespace setting _ignoreWhitespace = !results.Options["w"].IsPresent; // Load transforms string[] transformFiles = (string[])results.Options["xsl"].Value; if (transformFiles == null || transformFiles.Length == 0) { if (logger != null) { logger.WriteLine("No transform file is found in the command arguments.", BuildLoggerLevel.Error); } return(false); } _transformFiles = new List <string>(); for (int i = 0; i < transformFiles.Length; i++) { string transformFile = transformFiles[i]; if (transformFile != null && transformFile.Length != 0) { _transformFiles.Add(transformFile.Replace("\"", String.Empty)); } } // Compose the arguments if (results.Options["arg"].IsPresent) { if (_xsltArguments == null) { _xsltArguments = new Dictionary <string, string>(); } string[] nameValueStrings = (string[])results.Options["arg"].Value; foreach (string nameValueString in nameValueStrings) { string[] nameValuePair = nameValueString.Split('='); if (nameValuePair.Length != 2) { continue; } _xsltArguments.Add(nameValuePair[0], nameValuePair[1]); } } _inputFile = Environment.ExpandEnvironmentVariables( results.UnusedArguments[0]); if (_inputFile != null && _inputFile.Length != 0) { _inputFile = Path.GetFullPath(_inputFile.Replace("\"", String.Empty)); } _outputFile = Environment.ExpandEnvironmentVariables( (string)results.Options["out"].Value); if (_outputFile != null && _outputFile.Length != 0) { _outputFile = Path.GetFullPath(_outputFile.Replace("\"", String.Empty)); } return(this.IsDirectSandcastle()); }
//===================================================================== /// <summary> /// Main program entry point /// </summary> /// <param name="args">Command line arguments</param> /// <returns>Zero on success or non-zero on failure</returns> public static int Main(string[] args) { string path, version, framework = null, assemblyPath, typeName; // Write banner ConsoleApplication.WriteBanner(); // Specify options OptionCollection options = new OptionCollection(); options.Add(new SwitchOption("?", "Show this help page.")); options.Add(new StringOption("out", "Specify an output file. If unspecified, output goes to the " + "console.", "outputFilePath")); options.Add(new StringOption("config", "Specify a configuration file. If unspecified, " + "MRefBuilder.config is used", "configFilePath")); options.Add(new ListOption("dep", "Specify assemblies to load for dependencies.", "dependencyAssembly")); options.Add(new BooleanOption("internal", "Specify whether to document internal as well as " + "externally exposed APIs. *** DEPRECATED: Use the visibility settings in the MRefBuilder.config " + "file instead which provide finer grained control over the exposed API members.")); // Process options ParseArgumentsResult results = options.ParseArguments(args); if (results.Options["?"].IsPresent) { Console.WriteLine("MRefBuilder [options] assemblies"); options.WriteOptionSummary(Console.Out); return(1); } // Check for invalid options if (!results.Success) { results.WriteParseErrors(Console.Out); return(1); } // Check for missing or extra assembly directories if (results.UnusedArguments.Count < 1) { Console.WriteLine("Specify at least one assembly to reflect."); return(1); } // Load the configuration file XPathDocument config; string configDirectory = ComponentUtilities.ToolsFolder, configFile = Path.Combine(ComponentUtilities.ToolsFolder, "MRefBuilder.config"); if (results.Options["config"].IsPresent) { configFile = (string)results.Options["config"].Value; configDirectory = Path.GetDirectoryName(configFile); } try { config = new XPathDocument(configFile); } catch (IOException e) { ConsoleApplication.WriteMessage(LogLevel.Error, "An error occurred while attempting to read " + "the configuration file '{0}'. The error message is: {1}", configFile, e.Message); return(1); } catch (UnauthorizedAccessException e) { ConsoleApplication.WriteMessage(LogLevel.Error, "An error occurred while attempting to read " + "the configuration file '{0}'. The error message is: {1}", configFile, e.Message); return(1); } catch (XmlException e) { ConsoleApplication.WriteMessage(LogLevel.Error, "The configuration file '{0}' is not " + "well-formed. The error message is: {1}", configFile, e.Message); return(1); } // Adjust the target platform XPathNodeIterator platformNodes = config.CreateNavigator().Select("/configuration/dduetools/platform"); if (platformNodes.MoveNext()) { XPathNavigator platformNode = platformNodes.Current; version = platformNode.GetAttribute("version", String.Empty); path = platformNode.GetAttribute("path", String.Empty); // !EFW - Added support for the new platform attributes and the framework XML file if (!String.IsNullOrEmpty(version) && !String.IsNullOrEmpty(path)) { // Set the framework using the legacy attributes. If set properly, they will document // other framework types but it uses the standard .NET assemblies which contain more // classes and methods that are not relevant to the other frameworks. path = Environment.ExpandEnvironmentVariables(path); if (!Directory.Exists(path)) { ConsoleApplication.WriteMessage(LogLevel.Error, "The specified target platform " + "directory '{0}' does not exist.", path); return(1); } if (version == "2.0") { TargetPlatform.SetToV2(path); } else if (version == "1.1") { TargetPlatform.SetToV1_1(path); } else if (version == "1.0") { TargetPlatform.SetToV1(path); } else { ConsoleApplication.WriteMessage(LogLevel.Error, "Unknown target platform " + "version '{0}'.", version); return(1); } } else { // Use the new framework definition file framework = platformNode.GetAttribute("framework", String.Empty); if (!String.IsNullOrEmpty(framework) && !String.IsNullOrEmpty(version)) { TargetPlatform.SetFrameworkInformation(framework, version); } else { ConsoleApplication.WriteMessage(LogLevel.Error, "Unknown target framework " + "version '{0} {1}'.", framework, version); return(1); } } } // Create an API member namer ApiNamer namer; // Apply a different naming method to assemblies using the Windows Store or Windows Phone frameworks if (framework == ".NETCore" || framework == ".NETPortable" || framework == "WindowsPhone" || framework == "WindowsPhoneApp") { namer = new WindowsStoreAndPhoneNamer(); } else { namer = new OrcasNamer(); } XPathNavigator namerNode = config.CreateNavigator().SelectSingleNode("/configuration/dduetools/namer"); if (namerNode != null) { assemblyPath = namerNode.GetAttribute("assembly", String.Empty); typeName = namerNode.GetAttribute("type", String.Empty); assemblyPath = Environment.ExpandEnvironmentVariables(assemblyPath); if (!Path.IsPathRooted(assemblyPath)) { assemblyPath = Path.Combine(configDirectory, assemblyPath); } try { Assembly assembly = Assembly.LoadFrom(assemblyPath); namer = (ApiNamer)assembly.CreateInstance(typeName); if (namer == null) { ConsoleApplication.WriteMessage(LogLevel.Error, "The type '{0}' was not found in the " + "component assembly '{1}'.", typeName, assemblyPath); return(1); } } catch (IOException e) { ConsoleApplication.WriteMessage(LogLevel.Error, "A file access error occurred while " + "attempting to load the component assembly '{0}'. The error message is: {1}", assemblyPath, e.Message); return(1); } catch (UnauthorizedAccessException e) { ConsoleApplication.WriteMessage(LogLevel.Error, "A file access error occurred while " + "attempting to load the component assembly '{0}'. The error message is: {1}", assemblyPath, e.Message); return(1); } catch (BadImageFormatException) { ConsoleApplication.WriteMessage(LogLevel.Error, "The component assembly '{0}' is not a " + "valid managed assembly.", assemblyPath); return(1); } catch (TypeLoadException) { ConsoleApplication.WriteMessage(LogLevel.Error, "The type '{0}' was not found in the " + "component assembly '{1}'.", typeName, assemblyPath); return(1); } catch (MissingMethodException) { ConsoleApplication.WriteMessage(LogLevel.Error, "No appropriate constructor exists for " + "the type'{0}' in the component assembly '{1}'.", typeName, assemblyPath); return(1); } catch (TargetInvocationException e) { ConsoleApplication.WriteMessage(LogLevel.Error, "An error occurred while initializing the " + "type '{0}' in the component assembly '{1}'. The error message and stack trace " + "follows: {2}", typeName, assemblyPath, e.InnerException); return(1); } catch (InvalidCastException) { ConsoleApplication.WriteMessage(LogLevel.Error, "The type '{0}' in the component assembly " + "'{1}' is not a component type.", typeName, assemblyPath); return(1); } } // Create a resolver AssemblyResolver resolver = new AssemblyResolver(); XPathNavigator resolverNode = config.CreateNavigator().SelectSingleNode("/configuration/dduetools/resolver"); if (resolverNode != null) { assemblyPath = resolverNode.GetAttribute("assembly", String.Empty); typeName = resolverNode.GetAttribute("type", String.Empty); assemblyPath = Environment.ExpandEnvironmentVariables(assemblyPath); if (!Path.IsPathRooted(assemblyPath)) { assemblyPath = Path.Combine(configDirectory, assemblyPath); } try { Assembly assembly = Assembly.LoadFrom(assemblyPath); resolver = (AssemblyResolver)assembly.CreateInstance(typeName, false, BindingFlags.Public | BindingFlags.Instance, null, new object[1] { resolverNode }, null, null); if (resolver == null) { ConsoleApplication.WriteMessage(LogLevel.Error, "The type '{0}' was not found in the " + "component assembly '{1}'.", typeName, assemblyPath); return(1); } } catch (IOException e) { ConsoleApplication.WriteMessage(LogLevel.Error, "A file access error occurred while " + "attempting to load the component assembly '{0}'. The error message is: {1}", assemblyPath, e.Message); return(1); } catch (UnauthorizedAccessException e) { ConsoleApplication.WriteMessage(LogLevel.Error, "A file access error occurred while " + "attempting to load the component assembly '{0}'. The error message is: {1}", assemblyPath, e.Message); return(1); } catch (BadImageFormatException) { ConsoleApplication.WriteMessage(LogLevel.Error, "The component assembly '{0}' is not a " + "valid managed assembly.", assemblyPath); return(1); } catch (TypeLoadException) { ConsoleApplication.WriteMessage(LogLevel.Error, "The type '{0}' was not found in the " + "component assembly '{1}'.", typeName, assemblyPath); return(1); } catch (MissingMethodException) { ConsoleApplication.WriteMessage(LogLevel.Error, "No appropriate constructor exists for " + "the type'{0}' in the component assembly '{1}'.", typeName, assemblyPath); return(1); } catch (TargetInvocationException e) { ConsoleApplication.WriteMessage(LogLevel.Error, "An error occurred while initializing the " + "type '{0}' in the component assembly '{1}'. The error message and stack trace " + "follows: {2}", typeName, assemblyPath, e.InnerException); return(1); } catch (InvalidCastException) { ConsoleApplication.WriteMessage(LogLevel.Error, "The type '{0}' in the component assembly " + "'{1}' is not a component type.", typeName, assemblyPath); return(1); } } resolver.UnresolvedAssemblyReference += UnresolvedAssemblyReferenceHandler; // Get a text writer for output TextWriter output = Console.Out; if (results.Options["out"].IsPresent) { string file = (string)results.Options["out"].Value; try { output = new StreamWriter(file, false, Encoding.UTF8); } catch (IOException e) { ConsoleApplication.WriteMessage(LogLevel.Error, "An error occurred while attempting to " + "create an output file. The error message is: {0}", e.Message); return(1); } catch (UnauthorizedAccessException e) { ConsoleApplication.WriteMessage(LogLevel.Error, "An error occurred while attempting to " + "create an output file. The error message is: {0}", e.Message); return(1); } } // Dependency directory string[] dependencies = new string[0]; if (results.Options["dep"].IsPresent) { dependencies = (string[])results.Options["dep"].Value; } try { // Create a builder ApiVisitor = new ManagedReflectionWriter(output, namer, resolver, new ApiFilter(config.CreateNavigator().SelectSingleNode("/configuration/dduetools"))); // If the deprecated /internal+ option is used, expose everything via the filter to mimic the // behavior of prior versions. if (results.Options["internal"].IsPresent && (bool)results.Options["internal"].Value) { ApiVisitor.ApiFilter.IncludeAttributes = ApiVisitor.ApiFilter.IncludeExplicitInterfaceImplementations = ApiVisitor.ApiFilter.IncludePrivates = ApiVisitor.ApiFilter.IncludePrivateFields = ApiVisitor.ApiFilter.IncludeInternals = ApiVisitor.ApiFilter.IncludeProtected = ApiVisitor.ApiFilter.IncludeSealedProtected = ApiVisitor.ApiFilter.IncludeInheritedMembers = ApiVisitor.ApiFilter.IncludeInheritedFrameworkMembers = ApiVisitor.ApiFilter.IncludeInheritedFrameworkPrivateMembers = ApiVisitor.ApiFilter.IncludeInheritedFrameworkInternalMembers = ApiVisitor.ApiFilter.IncludeNoPIATypes = true; ApiVisitor.ApiFilter.IncludeProtectedInternalAsProtected = false; } // Register add-ins to the builder XPathNodeIterator addinNodes = config.CreateNavigator().Select("/configuration/dduetools/addins/addin"); foreach (XPathNavigator addinNode in addinNodes) { assemblyPath = addinNode.GetAttribute("assembly", String.Empty); typeName = addinNode.GetAttribute("type", String.Empty); assemblyPath = Environment.ExpandEnvironmentVariables(assemblyPath); if (!Path.IsPathRooted(assemblyPath)) { assemblyPath = Path.Combine(configDirectory, assemblyPath); } try { Assembly assembly = Assembly.LoadFrom(assemblyPath); MRefBuilderAddIn addin = (MRefBuilderAddIn)assembly.CreateInstance(typeName, false, BindingFlags.Public | BindingFlags.Instance, null, new object[2] { ApiVisitor, addinNode }, null, null); if (addin == null) { ConsoleApplication.WriteMessage(LogLevel.Error, "The type '{0}' was not found in " + "the add-in assembly '{1}'.", typeName, assemblyPath); return(1); } } catch (IOException e) { ConsoleApplication.WriteMessage(LogLevel.Error, "A file access error occurred while " + "attempting to load the add-in assembly '{0}'. The error message is: {1}", assemblyPath, e.Message); return(1); } catch (BadImageFormatException) { ConsoleApplication.WriteMessage(LogLevel.Error, "The add-in assembly '{0}' is not a " + "valid managed assembly.", assemblyPath); return(1); } catch (TypeLoadException) { ConsoleApplication.WriteMessage(LogLevel.Error, "The type '{0}' was not found in the " + "add-in assembly '{1}'.", typeName, assemblyPath); return(1); } catch (MissingMethodException) { ConsoleApplication.WriteMessage(LogLevel.Error, "No appropriate constructor exists " + "for the type '{0}' in the add-in assembly '{1}'.", typeName, assemblyPath); return(1); } catch (TargetInvocationException e) { ConsoleApplication.WriteMessage(LogLevel.Error, "An error occurred while initializing " + "the type '{0}' in the add-in assembly '{1}'. The error message and stack trace " + "follows: {2}", typeName, assemblyPath, e.InnerException); return(1); } catch (InvalidCastException) { ConsoleApplication.WriteMessage(LogLevel.Error, "The type '{0}' in the add-in " + "assembly '{1}' is not an MRefBuilderAddIn type.", typeName, assemblyPath); return(1); } } // Load dependencies foreach (string dependency in dependencies) { try { // Expand environment variables path = Environment.ExpandEnvironmentVariables(dependency); // If x86 but it didn't exist, assume it's a 32-bit system and change the name if (path.IndexOf("%ProgramFiles(x86)%", StringComparison.Ordinal) != -1) { path = Environment.ExpandEnvironmentVariables(path.Replace("(x86)", String.Empty)); } ApiVisitor.LoadAccessoryAssemblies(path); } catch (IOException e) { ConsoleApplication.WriteMessage(LogLevel.Error, "An error occurred while loading " + "dependency assemblies. The error message is: {0}", e.Message); return(1); } } // Parse the assemblies foreach (string dllPath in results.UnusedArguments) { try { // Expand environment variables path = Environment.ExpandEnvironmentVariables(dllPath); // If x86 but it didn't exist, assume it's a 32-bit system and change the name if (path.IndexOf("%ProgramFiles(x86)%", StringComparison.Ordinal) != -1) { path = Environment.ExpandEnvironmentVariables(path.Replace("(x86)", String.Empty)); } ApiVisitor.LoadAssemblies(path); } catch (IOException e) { ConsoleApplication.WriteMessage(LogLevel.Error, "An error occurred while loading " + "assemblies for reflection. The error message is: {0}", e.Message); return(1); } } ConsoleApplication.WriteMessage(LogLevel.Info, "Loaded {0} assemblies for reflection and " + "{1} dependency assemblies.", ApiVisitor.Assemblies.Count(), ApiVisitor.AccessoryAssemblies.Count()); ApiVisitor.VisitApis(); if (ApiVisitor.Canceled) { ConsoleApplication.WriteMessage(LogLevel.Error, "MRefBuilder task canceled"); } else { ConsoleApplication.WriteMessage(LogLevel.Info, "Wrote information on {0} namespaces, " + "{1} types, and {2} members", ApiVisitor.Namespaces.Count(), ApiVisitor.Types.Count(), ApiVisitor.Members.Count()); } } finally { if (ApiVisitor != null) { ApiVisitor.Dispose(); } if (results.Options["out"].IsPresent) { output.Close(); } } return((ApiVisitor != null && ApiVisitor.Canceled) ? 2 : 0); }
//===================================================================== /// <summary> /// Build the reflection data based on the command line arguments /// </summary> /// <param name="arguments">The command line arguments</param> /// <returns>Zero if successful, or a non-zero value on failure</returns> private int PerformBuild(ParseArgumentsResult arguments) { ReflectionDataSetDictionary rdsd; ReflectionDataSet dataSet; Version version = new Version(); string platform; int exitCode = 0; try { platform = (string)arguments.Options["platform"].Value; if (arguments.Options["version"].IsPresent && !Version.TryParse( (string)arguments.Options["version"].Value, out version)) { Console.WriteLine("Invalid version value"); return(1); } if (arguments.Options["path"].IsPresent) { rdsd = new ReflectionDataSetDictionary((string[])arguments.Options["path"].Value); } else { rdsd = new ReflectionDataSetDictionary(null); } if (version.Major != 0) { dataSet = rdsd.CoreFrameworkMatching(platform, version, true); } else { dataSet = rdsd.CoreFrameworkMostRecent(platform); } if (dataSet == null) { Console.WriteLine("A suitable framework could not be found for the given parameters"); return(1); } Console.WriteLine("Building reflection data for {0} found in {1}", dataSet.Title, dataSet.Filename); using (var bp = new BuildProcess(dataSet) { ProgressProvider = this }) { bp.Build(); } } catch (Exception ex) { exitCode = 1; Debug.WriteLine(ex.ToString()); Console.WriteLine("\r\n\r\nUnable to generate reflection data files: " + ex.Message + "\r\n"); } return(exitCode); }
//===================================================================== /// <summary> /// Main program entry point /// </summary> /// <param name="args">Command line arguments</param> /// <returns>Zero on success, a non-zero value on failure</returns> public static int Main(string[] args) { List <string> namespaces = new List <string>(); XPathNavigator projectRoot = null; int maxParts = 2, groupCount = 0; ConsoleApplication.WriteBanner(); OptionCollection options = new OptionCollection { new SwitchOption("?", "Show this help page."), new StringOption("out", "Specify an output filename. If unspecified, output goes to the " + "console.", "outputFile"), new StringOption("maxParts", "Specify the maximum number of namespace parts to consider " + "when creating groups. A higher value creates more groups. The default (and minimum) " + "is 2.", "999") }; ParseArgumentsResult result = options.ParseArguments(args); if (result.Options["?"].IsPresent) { Console.WriteLine("AddNamespaceGroups [options] reflectionDataFile"); options.WriteOptionSummary(Console.Out); return(0); } if (!result.Success) { result.WriteParseErrors(Console.Out); return(1); } if (result.UnusedArguments.Count != 1) { Console.WriteLine("Specify one reflection data file."); return(1); } if (result.Options["maxParts"].IsPresent && !Int32.TryParse((string)result.Options["maxParts"].Value, out maxParts)) { maxParts = 0; } if (maxParts < 2) { ConsoleApplication.WriteMessage(LogLevel.Warn, "maxParts option value is not valid. It must " + "be a valid integer with a minimum value of 2"); } // Get a text writer for output TextWriter output = Console.Out; if (result.Options["out"].IsPresent) { string file = (string)result.Options["out"].Value; try { output = new StreamWriter(file, false, Encoding.UTF8); } catch (IOException e) { ConsoleApplication.WriteMessage(LogLevel.Error, "An error occurred while attempting to " + "create an output file. The error message is: {0}", e.Message); return(1); } catch (UnauthorizedAccessException e) { ConsoleApplication.WriteMessage(LogLevel.Error, "An error occurred while attempting to " + "create an output file. The error message is: {0}", e.Message); return(1); } } try { XPathDocument source = new XPathDocument(result.UnusedArguments[0]); XmlWriterSettings settings = new XmlWriterSettings(); settings.Indent = true; settings.CloseOutput = result.Options["out"].IsPresent; using (XmlWriter xw = XmlWriter.Create(output, settings)) { // Copy the reflection element xw.WriteStartDocument(); xw.WriteStartElement("reflection"); var reflection = source.CreateNavigator().SelectSingleNode("reflection"); var elementNamespaces = reflection.GetNamespacesInScope(XmlNamespaceScope.ExcludeXml); foreach (var ns in elementNamespaces.Keys.Reverse()) { xw.WriteAttributeString("xmlns", ns, null, elementNamespaces[ns]); } if (reflection.MoveToFirstAttribute()) { do { xw.WriteAttributeString(reflection.Prefix, reflection.Name, null, reflection.Value + "X"); } while(reflection.MoveToNextAttribute()); reflection.MoveToParent(); } // Copy assembly elements var assemblies = reflection.SelectSingleNode("assemblies"); if (assemblies != null) { assemblies.WriteSubtree(xw); } // Copy the API elements and track all of the namespace elements xw.WriteStartElement("apis"); foreach (XPathNavigator api in reflection.Select("apis/api")) { string id = (string)api.Evaluate("string(@id)"); if (id != null && id.Length > 1 && id[1] == ':' && (id[0] == 'N' || id[0] == 'R')) { if (id.StartsWith("N:", StringComparison.Ordinal)) { namespaces.Add(id); api.WriteSubtree(xw); } else { projectRoot = api; // Project root node gets replaced if present } } else { api.WriteSubtree(xw); } if (Canceled) { break; } } // Group namespaces and write out the group entries foreach (var group in GroupNamespaces(namespaces, maxParts, (projectRoot != null))) { if (Canceled) { break; } if (group.Namespace.Length == 0) { // If the namespace is blank, it's the root group. If a project root element was // specified, replace its element list with the one from this group. If no project // root element was found, write the root group out as a placeholder for the TOC // transformation so that it can determine the root level content. if (projectRoot != null) { xw.WriteStartElement("api"); xw.WriteAttributeString("id", projectRoot.GetAttribute("id", String.Empty)); projectRoot.MoveToChild("topicdata", String.Empty); projectRoot.WriteSubtree(xw); xw.WriteStartElement("elements"); foreach (string child in group.Children.OrderBy(n => n.Substring(2))) { xw.WriteStartElement("element"); xw.WriteAttributeString("api", child); xw.WriteEndElement(); } xw.WriteEndElement(); // elements xw.WriteEndElement(); // api } else { xw.WriteStartElement("api"); xw.WriteAttributeString("id", "G:"); xw.WriteStartElement("topicdata"); xw.WriteAttributeString("group", "rootGroup"); xw.WriteEndElement(); xw.WriteStartElement("elements"); foreach (string child in group.Children.OrderBy(n => n.Substring(2))) { xw.WriteStartElement("element"); xw.WriteAttributeString("api", child); xw.WriteEndElement(); } xw.WriteEndElement(); // elements xw.WriteEndElement(); // api } } else { groupCount++; xw.WriteStartElement("api"); xw.WriteAttributeString("id", group.Namespace); xw.WriteStartElement("topicdata"); xw.WriteAttributeString("group", "api"); xw.WriteEndElement(); xw.WriteStartElement("apidata"); xw.WriteAttributeString("name", group.Namespace.Substring(2)); xw.WriteAttributeString("group", "namespaceGroup"); xw.WriteEndElement(); xw.WriteStartElement("elements"); foreach (string child in group.Children.OrderBy(n => n.Substring(2))) { xw.WriteStartElement("element"); xw.WriteAttributeString("api", child); xw.WriteEndElement(); } xw.WriteEndElement(); // elements xw.WriteEndElement(); // api } } xw.WriteEndElement(); // apis xw.WriteEndElement(); // reflection xw.WriteEndDocument(); } if (!Canceled) { ConsoleApplication.WriteMessage(LogLevel.Info, "Added {0} namespace group entries", groupCount); } } catch (Exception ex) { Console.WriteLine("Unexpected error adding namespace groups to reflection data. Reason: {0}", ex.Message); return(1); } return(Canceled ? 1 : 0); }
//===================================================================== /// <summary> /// This is overridden to handle command line builds /// </summary> /// <param name="e">The event arguments</param> protected override void OnStartup(StartupEventArgs e) { int exitCode = 0; base.OnStartup(e); try { MSBuildLocator.RegisterDefaults(); } catch (Exception ex) { Console.WriteLine("Unable to register MSBuild defaults: " + ex.Message + "\r\n\r\n" + "You probably need to install the Microsoft Build Tools for Visual Studio 2017 or later."); return; } // If command line options are present, perform a build if (e.Args.Length != 0) { Assembly application = Assembly.GetCallingAssembly(); AssemblyName applicationData = application.GetName(); FileVersionInfo fvi = FileVersionInfo.GetVersionInfo(application.Location); Console.WriteLine("{0} (v{1})", applicationData.Name, fvi.ProductVersion); object[] copyrightAttributes = application.GetCustomAttributes(typeof(AssemblyCopyrightAttribute), true); foreach (AssemblyCopyrightAttribute copyrightAttribute in copyrightAttributes) { Console.WriteLine(copyrightAttribute.Copyright); } // Specify options OptionCollection options = new OptionCollection { new SwitchOption("?", "Show this help page."), new StringOption("platform", "Specify the platform to use for the build", "platformName") { RequiredMessage = "A platform parameter value is required" }, new StringOption("version", "Specify the version to use for the build. If not " + "specified, the most recent version for the specified platform is used.", "version"), new ListOption("path", "Specify additional paths to search for reflection data set " + "files if necessary.", "dataSetPath") }; // Process options ParseArgumentsResult parsedArguments = options.ParseArguments(e.Args); if (parsedArguments.Options["?"].IsPresent) { Console.WriteLine("ReflectionDataManager [options]"); options.WriteOptionSummary(Console.Out); exitCode = 1; } else if (!parsedArguments.Success) { parsedArguments.WriteParseErrors(Console.Out); exitCode = 1; } if (exitCode == 0) { exitCode = PerformBuild(parsedArguments); } this.Shutdown(exitCode); return; } // Run interactively IntPtr hWnd = Process.GetCurrentProcess().MainWindowHandle; // If we own the console, hide it if (hWnd != IntPtr.Zero) { ShowWindow(hWnd, 0); } new MainWindow().ShowDialog(); this.Shutdown(); }
public static int Main(string[] args) { ConsoleApplication.WriteBanner(); #region read command line arguments, and setup config // specify options OptionCollection options = new OptionCollection(); options.Add(new SwitchOption("?", "Show this help page.")); options.Add(new StringOption("config", "Specify a configuration file.", "configFilePath")); // process options ParseArgumentsResult results = options.ParseArguments(args); // process help option if (results.Options["?"].IsPresent) { Console.WriteLine("TocBuilder [options] rootDirectory"); options.WriteOptionSummary(Console.Out); return(0); } // check for invalid options if (!results.Success) { results.WriteParseErrors(Console.Out); return(1); } // check for manifest if (results.UnusedArguments.Count != 1) { Console.WriteLine("You must supply exactly one manifest file."); return(1); } string manifest = results.UnusedArguments[0]; // Load the configuration file XPathDocument configuration; try { if (results.Options["config"].IsPresent) { configuration = ConsoleApplication.GetConfigurationFile((string)results.Options["config"].Value); } else { configuration = ConsoleApplication.GetConfigurationFile(); } } catch (IOException e) { ConsoleApplication.WriteMessage(LogLevel.Error, String.Format("The specified configuration file could not be loaded. The error message is: {0}", e.Message)); return(1); } catch (XmlException e) { ConsoleApplication.WriteMessage(LogLevel.Error, String.Format("The specified configuration file is not well-formed. The error message is: {0}", e.Message)); return(1); } #endregion // create a BuildAssembler to do the work BuildAssembler buildAssembler = new BuildAssembler(); try { // load the context XPathNavigator contextNode = configuration.CreateNavigator().SelectSingleNode("/configuration/dduetools/builder/context"); if (contextNode != null) { buildAssembler.Context.Load(contextNode); } // load the build components XPathNavigator componentsNode = configuration.CreateNavigator().SelectSingleNode("/configuration/dduetools/builder/components"); if (componentsNode != null) { buildAssembler.AddComponents(componentsNode); } // proceed thorugh the build manifest, processing all topics named there int count = buildAssembler.Apply(manifest); ConsoleApplication.WriteMessage(LogLevel.Info, String.Format("Processed {0} topics", count)); } finally { buildAssembler.Dispose(); } return(0); }
//===================================================================== /// <summary> /// This is overridden to handle command line builds /// </summary> /// <param name="e">The event arguments</param> protected override void OnStartup(StartupEventArgs e) { int exitCode = 0; base.OnStartup(e); // If command line options are present, perform a build if (e.Args.Length != 0) { ConsoleApplication.WriteBanner(); // Specify options OptionCollection options = new OptionCollection(); options.Add(new SwitchOption("?", "Show this help page.")); options.Add(new StringOption("platform", "Specify the platform to use for the build", "platformName") { RequiredMessage = "A platform parameter value is required" }); options.Add(new StringOption("version", "Specify the version to use for the build. If not " + "specified, the most recent version for the specified platform is used.", "version")); options.Add(new ListOption("path", "Specify additional paths to search for reflection data set " + "files if necessary.", "dataSetPath")); // Process options ParseArgumentsResult parsedArguments = options.ParseArguments(e.Args); if (parsedArguments.Options["?"].IsPresent) { Console.WriteLine("ReflectionDataManager [options]"); options.WriteOptionSummary(Console.Out); exitCode = 1; } else if (!parsedArguments.Success) { parsedArguments.WriteParseErrors(Console.Out); exitCode = 1; } if (exitCode == 0) { exitCode = PerformBuild(parsedArguments); } this.Shutdown(exitCode); return; } // Run interactively IntPtr hWnd = Process.GetCurrentProcess().MainWindowHandle; // If we own the console, hide it if (hWnd != IntPtr.Zero) { ShowWindow(hWnd, 0); } new MainWindow().ShowDialog(); this.Shutdown(); }