├── readme.md ├── readme.pdf └── source ├── App.config ├── Binding.cs ├── Extensions.cs ├── Program.cs ├── Properties └── AssemblyInfo.cs ├── packages.config ├── packages ├── CsvHelper.9.2.3 │ ├── .signature.p7s │ ├── CsvHelper.9.2.3.nupkg │ └── lib │ │ ├── net45 │ │ ├── CsvHelper.dll │ │ └── CsvHelper.xml │ │ └── netstandard2.0 │ │ ├── CsvHelper.dll │ │ └── CsvHelper.xml └── FluentCommandLineParser.1.4.3 │ ├── .signature.p7s │ ├── FluentCommandLineParser.1.4.3.nupkg │ └── lib │ ├── net35-Client │ ├── FluentCommandLineParser.dll │ ├── FluentCommandLineParser.dll.CodeAnalysisLog.xml │ └── FluentCommandLineParser.xml │ └── net35 │ ├── FluentCommandLineParser.dll │ ├── FluentCommandLineParser.pdb │ └── FluentCommandLineParser.xml ├── wmi-parser.csproj └── wmi-parser.sln /readme.md: -------------------------------------------------------------------------------- 1 | # wmi-parser 2 | 3 | ## TLDR 4 | 5 | There is nothing new here! It is just a rewrite of @DavidPany excellent work into WMI parsing. The original pythin code can be found here: 6 | 7 | https://github.com/davidpany/WMI_Forensics 8 | 9 | ## Background 10 | 11 | I need WMI parsing for autorunner, so converted the original python code to C#, and thought it might as well be available as a standalone tool. The only added feature is CSV export 12 | 13 | ## Example 14 | ``` 15 | .\wmi-parser.exe -i .\OBJECTS.DATA 16 | 17 | wmi-parser v0.0.1 18 | 19 | Author: Mark Woan / woanware (markwoan@gmail.com) 20 | https://github.com/woanware/wmi-parser 21 | 22 | SCM Event Log Consumer-SCM Event Log Filter - (Common binding based on consumer and filter names, possibly legitimate) 23 | Consumer: NTEventLogEventConsumer ~ SCM Event Log Consumer ~ sid ~ Service Control Manager 24 | 25 | Filter: 26 | Filter Name : SCM Event Log Filter 27 | Filter Query: select * from MSFT_SCMEventLogEvent 28 | 29 | BadStuff-DeviceDocked 30 | 31 | Name: BadStuff 32 | Type: CommandLineEventConsumer 33 | Arguments: powershell.exe -NoP Start-Process ('badstuff.exe') 34 | 35 | Filter: 36 | Filter Name : DeviceDocked 37 | Filter Query: SELECT * FROM Win32_SystemConfigurationChangeEvent 38 | ``` 39 | -------------------------------------------------------------------------------- /readme.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/woanware/wmi-parser/754ce11d096e5b01ef496c02e4df46ffccd4dcf8/readme.pdf -------------------------------------------------------------------------------- /source/App.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /source/Binding.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace wmi 8 | { 9 | /// 10 | /// 11 | /// 12 | internal class Binding 13 | { 14 | public string Name { get; set; } 15 | public string Filter { get; set; } 16 | public string Query { get; set; } 17 | public string Type { get; set; } 18 | public string Arguments { get; set; } 19 | public string Other { get; set; } 20 | 21 | public Binding(string name, string filter) 22 | { 23 | Name = name; 24 | Filter = filter; 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /source/Extensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace wmi 8 | { 9 | public static class Extensions 10 | { 11 | /// 12 | /// Get the array slice between the two indexes. 13 | /// ... Inclusive for start index, exclusive for end index. 14 | /// 15 | public static T[] Slice(this T[] source, int start, int end) 16 | { 17 | // Handles negative ends. 18 | if (end < 0) 19 | { 20 | end = source.Length + end; 21 | } 22 | int len = end - start; 23 | 24 | // Return new array. 25 | T[] res = new T[len]; 26 | for (int i = 0; i < len; i++) 27 | { 28 | res[i] = source[i + start]; 29 | } 30 | return res; 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /source/Program.cs: -------------------------------------------------------------------------------- 1 | using CsvHelper; 2 | using Fclp; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.IO; 6 | using System.Reflection; 7 | using System.Text.RegularExpressions; 8 | 9 | namespace wmi 10 | { 11 | /// 12 | /// 13 | /// 14 | internal class ApplicationArguments 15 | { 16 | public string Output { get; set; } 17 | public string Input { get; set; } 18 | } 19 | 20 | class Program 21 | { 22 | #region Member Variables 23 | private static FluentCommandLineParser fclp; 24 | #endregion 25 | 26 | /// 27 | /// Application entry point 28 | /// 29 | /// 30 | static void Main(string[] args) 31 | { 32 | if (ProcessCommandLine(args) == false) 33 | { 34 | return; 35 | } 36 | 37 | if (CheckCommandLine() == false) 38 | { 39 | return; 40 | } 41 | 42 | string data = File.ReadAllText(fclp.Object.Input); 43 | 44 | Regex regexConsumer = new Regex(@"([\w_]*EventConsumer)\.Name=""([\w\s]*)""", RegexOptions.Multiline | RegexOptions.IgnoreCase | RegexOptions.Compiled); 45 | var matchesConsumer = regexConsumer.Matches(data); 46 | 47 | Regex regexFilter = new Regex(@"_EventFilter\.Name=""([\w\s]*)""", RegexOptions.Multiline | RegexOptions.IgnoreCase | RegexOptions.Compiled); 48 | var matchesFilter = regexFilter.Matches(data); 49 | 50 | List bindings = new List(); 51 | for (int index = 0; index < matchesConsumer.Count; index++) 52 | { 53 | bindings.Add(new Binding(matchesConsumer[index].Groups[2].Value, matchesFilter[index].Groups[1].Value)); 54 | } 55 | 56 | foreach (var b in bindings) 57 | { 58 | Regex regexEventConsumer = new Regex(@"\x00CommandLineEventConsumer\x00\x00(.*?)\x00.*?" + b.Name + "\x00\x00?([^\x00]*)?", RegexOptions.Multiline); 59 | 60 | var matches = regexEventConsumer.Matches(data); 61 | foreach (Match m in matches) 62 | { 63 | b.Type = "CommandLineEventConsumer"; 64 | b.Arguments = m.Groups[1].Value; 65 | } 66 | 67 | regexEventConsumer = new Regex(@"(\w*EventConsumer)(.*?)(" + b.Name + @")(\x00\x00)([^\x00]*)(\x00\x00)([^\x00]*)", RegexOptions.Multiline); 68 | matches = regexEventConsumer.Matches(data); 69 | foreach (Match m in matches) 70 | { 71 | b.Other = string.Format("{0} ~ {1} ~ {2} ~ {3}", m.Groups[1], m.Groups[3], m.Groups[5], m.Groups[7]); 72 | } 73 | 74 | regexEventConsumer = new Regex(@"(" + b.Filter + ")(\x00\x00)([^\x00]*)(\x00\x00)", RegexOptions.Multiline); 75 | matches = regexEventConsumer.Matches(data); 76 | foreach (Match m in matches) 77 | { 78 | b.Query = m.Groups[3].Value; 79 | } 80 | } 81 | 82 | OutputToConsole(bindings); 83 | 84 | if (fclp.Object.Output != null) 85 | { 86 | OutputToFile(bindings); 87 | } 88 | } 89 | 90 | /// 91 | /// 92 | /// 93 | private static bool ProcessCommandLine(string[] args) 94 | { 95 | fclp = new FluentCommandLineParser 96 | { 97 | IsCaseSensitive = false 98 | }; 99 | 100 | fclp.Setup(arg => arg.Input) 101 | .As('i') 102 | .Required() 103 | .WithDescription("Input file (OBJECTS.DATA)"); 104 | 105 | fclp.Setup(arg => arg.Output) 106 | .As('o') 107 | .WithDescription("Output directory for analysis results"); 108 | 109 | var header = 110 | $"\r\n{Assembly.GetExecutingAssembly().GetName().Name} v{Assembly.GetExecutingAssembly().GetName().Version.ToString(3)}" + 111 | "\r\n\r\nAuthor: Mark Woan / woanware (markwoan@gmail.com)" + 112 | "\r\nhttps://github.com/woanware/wmi-parser"; 113 | 114 | // Sets up the parser to execute the callback when -? or --help is supplied 115 | fclp.SetupHelp("?", "help") 116 | .WithHeader(header) 117 | .Callback(text => Console.WriteLine(text)); 118 | 119 | var result = fclp.Parse(args); 120 | 121 | if (result.HelpCalled) 122 | { 123 | return false; 124 | } 125 | 126 | if (result.HasErrors) 127 | { 128 | Console.WriteLine(""); 129 | Console.WriteLine(result.ErrorText); 130 | fclp.HelpOption.ShowHelp(fclp.Options); 131 | return false; 132 | } 133 | 134 | Console.WriteLine(header); 135 | Console.WriteLine(""); 136 | 137 | return true; 138 | } 139 | 140 | /// 141 | /// Performs some basic command line parameter checking 142 | /// 143 | /// 144 | private static bool CheckCommandLine() 145 | { 146 | FileAttributes fa = File.GetAttributes(fclp.Object.Input); 147 | if ((fa & FileAttributes.Directory) == FileAttributes.Directory) 148 | { 149 | if (Directory.Exists(fclp.Object.Input) == false) 150 | { 151 | Console.WriteLine("Input directory (-i) does not exist"); 152 | return false; 153 | } 154 | } 155 | else 156 | { 157 | if (File.Exists(fclp.Object.Input) == false) 158 | { 159 | Console.WriteLine("Input file (-i) does not exist"); 160 | return false; 161 | } 162 | } 163 | 164 | if (fclp.Object.Output != null) 165 | { 166 | if (Directory.Exists(fclp.Object.Output) == false) 167 | { 168 | Console.WriteLine("Output directory (-o) does not exist"); 169 | return false; 170 | } 171 | } 172 | 173 | return true; 174 | } 175 | 176 | /// 177 | /// 178 | /// 179 | /// 180 | private static void OutputToConsole(List bindings) 181 | { 182 | // Output the data 183 | foreach (var b in bindings) 184 | { 185 | if ((b.Name.Contains("BVTConsumer") && b.Filter.Contains("BVTFilter")) || (b.Name.Contains("SCM Event Log Consumer") && b.Filter.Contains("SCM Event Log Filter"))) 186 | { 187 | Console.WriteLine(" {0}-{1} - (Common binding based on consumer and filter names, possibly legitimate)", b.Name, b.Filter); 188 | } 189 | else 190 | { 191 | Console.WriteLine(" {0}-{1}\n", b.Name, b.Filter); 192 | } 193 | 194 | if (b.Type == "CommandLineEventConsumer") 195 | { 196 | Console.WriteLine(" Name: {0}", b.Name); 197 | Console.WriteLine(" Type: {0}", "CommandLineEventConsumer"); 198 | Console.WriteLine(" Arguments: {0}", b.Arguments); 199 | } 200 | else 201 | { 202 | Console.WriteLine(" Consumer: {0}", b.Other); 203 | } 204 | 205 | Console.WriteLine("\n Filter:"); 206 | Console.WriteLine(" Filter Name : {0} ", b.Filter); 207 | Console.WriteLine(" Filter Query: {0} ", b.Query); 208 | Console.WriteLine(""); 209 | } 210 | } 211 | 212 | /// 213 | /// 214 | /// 215 | /// 216 | private static void OutputToFile(List bindings) 217 | { 218 | using (FileStream fileStream = new FileStream(Path.Combine(fclp.Object.Output, "wmi-parser.tsv"), FileMode.Create, FileAccess.Write)) 219 | using (StreamWriter streamWriter = new StreamWriter(fileStream)) 220 | using (CsvWriter cw = new CsvHelper.CsvWriter(streamWriter)) 221 | { 222 | cw.Configuration.Delimiter = "\t"; 223 | // Write out the file headers 224 | cw.WriteField("Name"); 225 | cw.WriteField("Type"); 226 | cw.WriteField("Arguments"); 227 | cw.WriteField("Filter Name"); 228 | cw.WriteField("Filter Query"); 229 | cw.NextRecord(); 230 | 231 | foreach (var b in bindings) 232 | { 233 | cw.WriteField(b.Name); 234 | cw.WriteField(b.Type); 235 | cw.WriteField(b.Arguments); 236 | cw.WriteField(b.Filter); 237 | cw.WriteField(b.Query); 238 | cw.NextRecord(); ; 239 | } 240 | } 241 | } 242 | } 243 | } 244 | -------------------------------------------------------------------------------- /source/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("wmi-parser")] 9 | [assembly: AssemblyDescription("Parses the WMI object database...")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("woanware")] 12 | [assembly: AssemblyProduct("wmi-parser")] 13 | [assembly: AssemblyCopyright("Copyright © woanware 2018")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("183b0bcc-55ae-4336-be27-8a9a57a153af")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("0.0.1")] 36 | [assembly: AssemblyFileVersion("0.0.1")] 37 | -------------------------------------------------------------------------------- /source/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /source/packages/CsvHelper.9.2.3/.signature.p7s: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/woanware/wmi-parser/754ce11d096e5b01ef496c02e4df46ffccd4dcf8/source/packages/CsvHelper.9.2.3/.signature.p7s -------------------------------------------------------------------------------- /source/packages/CsvHelper.9.2.3/CsvHelper.9.2.3.nupkg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/woanware/wmi-parser/754ce11d096e5b01ef496c02e4df46ffccd4dcf8/source/packages/CsvHelper.9.2.3/CsvHelper.9.2.3.nupkg -------------------------------------------------------------------------------- /source/packages/CsvHelper.9.2.3/lib/net45/CsvHelper.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/woanware/wmi-parser/754ce11d096e5b01ef496c02e4df46ffccd4dcf8/source/packages/CsvHelper.9.2.3/lib/net45/CsvHelper.dll -------------------------------------------------------------------------------- /source/packages/CsvHelper.9.2.3/lib/netstandard2.0/CsvHelper.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/woanware/wmi-parser/754ce11d096e5b01ef496c02e4df46ffccd4dcf8/source/packages/CsvHelper.9.2.3/lib/netstandard2.0/CsvHelper.dll -------------------------------------------------------------------------------- /source/packages/FluentCommandLineParser.1.4.3/.signature.p7s: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/woanware/wmi-parser/754ce11d096e5b01ef496c02e4df46ffccd4dcf8/source/packages/FluentCommandLineParser.1.4.3/.signature.p7s -------------------------------------------------------------------------------- /source/packages/FluentCommandLineParser.1.4.3/FluentCommandLineParser.1.4.3.nupkg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/woanware/wmi-parser/754ce11d096e5b01ef496c02e4df46ffccd4dcf8/source/packages/FluentCommandLineParser.1.4.3/FluentCommandLineParser.1.4.3.nupkg -------------------------------------------------------------------------------- /source/packages/FluentCommandLineParser.1.4.3/lib/net35-Client/FluentCommandLineParser.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/woanware/wmi-parser/754ce11d096e5b01ef496c02e4df46ffccd4dcf8/source/packages/FluentCommandLineParser.1.4.3/lib/net35-Client/FluentCommandLineParser.dll -------------------------------------------------------------------------------- /source/packages/FluentCommandLineParser.1.4.3/lib/net35-Client/FluentCommandLineParser.dll.CodeAnalysisLog.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | Correct the spelling of 'Fclp' in namespace name 'Fclp'. 9 | 10 | 11 | 12 | 13 | 14 | 15 | Correct the spelling of 'Fclp' in namespace name 'Fclp.Internals'. 16 | 17 | 18 | 19 | 20 | 21 | 22 | Consider merging the types defined in 'Fclp.Internals.Errors' with another namespace. 23 | 24 | 25 | Correct the spelling of 'Fclp' in namespace name 'Fclp.Internals.Errors'. 26 | 27 | 28 | 29 | 30 | 31 | 32 | Consider merging the types defined in 'Fclp.Internals.Extensions' with another namespace. 33 | 34 | 35 | Correct the spelling of 'Fclp' in namespace name 'Fclp.Internals.Extensions'. 36 | 37 | 38 | 39 | 40 | 41 | 42 | Correct the spelling of 'Fclp' in namespace name 'Fclp.Internals.Parsing'. 43 | 44 | 45 | 46 | 47 | 48 | 49 | Correct the spelling of 'Fclp' in namespace name 'Fclp.Internals.Parsing.OptionParsers'. 50 | 51 | 52 | 53 | 54 | 55 | 56 | Consider merging the types defined in 'Fclp.Internals.Validators' with another namespace. 57 | 58 | 59 | Correct the spelling of 'Fclp' in namespace name 'Fclp.Internals.Validators'. 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | Sign 'FluentCommandLineParser.dll' with a strong name key. 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | In externally visible method 'CommandLineParserErrorFormatter.Format(IEnumerable<ICommandLineParserError>)', validate parameter 'parserErrors' before using it. 82 | 83 | 84 | 85 | 86 | 87 | 88 | Because the behavior of 'string.Format(string, object)' could vary based on the current user's locale settings, replace this call in 'CommandLineParserErrorFormatter.FormatExpectedOptionNotFoundError(ExpectedOptionNotFoundParseError)' with a call to 'string.Format(IFormatProvider, string, params object[])'. If the result of 'string.Format(IFormatProvider, string, params object[])' will be displayed to the user, specify 'CultureInfo.CurrentCulture' as the 'IFormatProvider' parameter. Otherwise, if the result will be stored and accessed by software, such as when it is persisted to disk or to a database, specify 'CultureInfo.InvariantCulture'. 89 | 90 | 91 | 92 | 93 | 94 | 95 | Because the behavior of 'string.Format(string, object, object, object)' could vary based on the current user's locale settings, replace this call in 'CommandLineParserErrorFormatter.FormatOptionSyntaxParseError(OptionSyntaxParseError)' with a call to 'string.Format(IFormatProvider, string, params object[])'. If the result of 'string.Format(IFormatProvider, string, params object[])' will be displayed to the user, specify 'CultureInfo.CurrentCulture' as the 'IFormatProvider' parameter. Otherwise, if the result will be stored and accessed by software, such as when it is persisted to disk or to a database, specify 'CultureInfo.InvariantCulture'. 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | Change 'List<ICommandLineOption>' in 'FluentCommandLineParser.Options' to use Collection<T>, ReadOnlyCollection<T> or KeyedCollection<K,V> 107 | 108 | 109 | 110 | 111 | 112 | 113 | Correct the spelling of the unrecognized token 'OptionFactory' in the literal '"OptionFactory is producing unexpected results."'. 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | Rename virtual/interface member 'ICommandLineOptionBuilderFluent<TProperty>.As(char)' so that it no longer conflicts with the reserved language keyword 'As'. Using a reserved keyword as the name of a virtual/interface member makes it harder for consumers in other languages to override/implement the member. 125 | 126 | 127 | 128 | 129 | 130 | 131 | Rename virtual/interface member 'ICommandLineOptionBuilderFluent<TProperty>.As(char, string)' so that it no longer conflicts with the reserved language keyword 'As'. Using a reserved keyword as the name of a virtual/interface member makes it harder for consumers in other languages to override/implement the member. 132 | 133 | 134 | 135 | 136 | 137 | 138 | Rename virtual/interface member 'ICommandLineOptionBuilderFluent<TProperty>.As(string)' so that it no longer conflicts with the reserved language keyword 'As'. Using a reserved keyword as the name of a virtual/interface member makes it harder for consumers in other languages to override/implement the member. 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | Change either member or parameter name 'callback' so that one differs from the other. 150 | 151 | 152 | 153 | 154 | 155 | 156 | Consider a design where 'ICommandLineOptionFluent<T>.CaptureAdditionalArguments(Action<IEnumerable<string>>)' doesn't nest generic type 'Action<IEnumerable<string>>'. 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | Rename virtual/interface member 'ICommandLineParserError.Option' so that it no longer conflicts with the reserved language keyword 'Option'. Using a reserved keyword as the name of a virtual/interface member makes it harder for consumers in other languages to override/implement the member. 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | Consider a design where 'ICommandLineParserResult.AdditionalOptionsFound' doesn't nest generic type 'IEnumerable<KeyValuePair<string, string>>'. 179 | 180 | 181 | 182 | 183 | 184 | 185 | The compound word 'UnMatched' in member name 'ICommandLineParserResult.UnMatchedOptions' exists as a discrete term. If your usage is intended to be single word, case it as 'Unmatched' or strip the first token entirely if it represents any sort of Hungarian notation. 186 | 187 | 188 | Correct the casing of 'Un' in member name 'ICommandLineParserResult.UnMatchedOptions' by changing it to 'UN'. 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | Rename virtual/interface member 'IFluentCommandLineParser<TBuildType>.Object' so that it no longer conflicts with the reserved language keyword 'Object'. Using a reserved keyword as the name of a virtual/interface member makes it harder for consumers in other languages to override/implement the member. 200 | 201 | 202 | 203 | 204 | 205 | 206 | Consider a design where 'IFluentCommandLineParser<TBuildType>.Setup<TProperty>(Expression<Func<TBuildType, TProperty>>)' doesn't nest generic type 'Expression<Func<TBuildType, TProperty>>'. 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | Change either member or parameter name 'callback' so that one differs from the other. 218 | 219 | 220 | 221 | 222 | 223 | 224 | Change either member or parameter name 'callback' so that one differs from the other. 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | Add [Serializable] to 'InvalidOptionNameException' as this type implements ISerializable. 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | Change the accessibility of 'OptionAlreadyExistsException.OptionAlreadyExistsException(SerializationInfo, StreamingContext)' to protected. 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | Add the following constructor to 'OptionSyntaxException': protected OptionSyntaxException(SerializationInfo, StreamingContext). 252 | Add the following constructor to 'OptionSyntaxException': public OptionSyntaxException(String). 253 | Add the following constructor to 'OptionSyntaxException': public OptionSyntaxException(String, Exception). 254 | 255 | 256 | 257 | 258 | 259 | 260 | Add the following constructor to 'UnsupportedTypeException': protected UnsupportedTypeException(SerializationInfo, StreamingContext). 261 | Add the following constructor to 'UnsupportedTypeException': public UnsupportedTypeException(String). 262 | Add the following constructor to 'UnsupportedTypeException': public UnsupportedTypeException(String, Exception). 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | Consider a design where 'CommandLineOptionBuilderFluent<TBuildType, TProperty>.CommandLineOptionBuilderFluent(IFluentCommandLineParser, TBuildType, Expression<Func<TBuildType, TProperty>>)' doesn't nest generic type 'Expression<Func<TBuildType, TProperty>>'. 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | In member 'EmptyHelpCommandLineOption.ShouldShowHelp(IEnumerable<ParsedOption>, StringComparison)', change parameter name 'commandLineArgs' to 'parsedOptions' in order to match the identifier as it has been declared in 'IHelpCommandLineOption.ShouldShowHelp(IEnumerable<ParsedOption>, StringComparison)'. 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | Either replace 'SpecialCharacters.OptionPrefix' with a strongly typed collection that cannot be changed, or replace the public field with a method that returns a clone of a private array. 298 | 299 | 300 | 301 | 302 | 303 | 304 | Either replace 'SpecialCharacters.OptionSuffix' with a strongly typed collection that cannot be changed, or replace the public field with a method that returns a clone of a private array. 305 | 306 | 307 | 308 | 309 | 310 | 311 | Either replace 'SpecialCharacters.ShortOptionPrefix' with a strongly typed collection that cannot be changed, or replace the public field with a method that returns a clone of a private array. 312 | 313 | 314 | 315 | 316 | 317 | 318 | Either replace 'SpecialCharacters.ValueAssignments' with a strongly typed collection that cannot be changed, or replace the public field with a method that returns a clone of a private array. 319 | 320 | 321 | 322 | 323 | 324 | 325 | The discrete term 'Whitespace' in member name 'SpecialCharacters.Whitespace' should be expressed as a compound word, 'WhiteSpace'. 326 | 327 | 328 | 329 | 330 | 331 | 332 | 333 | 334 | 335 | 336 | 337 | 338 | 339 | 340 | The discrete term 'Whitespace' in member name 'UsefulExtension.ContainsWhitespace(this string)' should be expressed as a compound word, 'WhiteSpace'. 341 | 342 | 343 | 344 | 345 | 346 | 347 | In externally visible method 'UsefulExtension.ElementAtOrDefault<T>(this T[], int, T)', validate parameter 'items' before using it. 348 | 349 | 350 | 351 | 352 | 353 | 354 | In externally visible method 'UsefulExtension.ForEach<TSource>(this IEnumerable<TSource>, Action<TSource>)', validate parameter 'enumerable' before using it. 355 | 356 | 357 | In externally visible method 'UsefulExtension.ForEach<TSource>(this IEnumerable<TSource>, Action<TSource>)', validate parameter 'action' before using it. 358 | 359 | 360 | 361 | 362 | 363 | 364 | In method 'UsefulExtension.IsWrappedInDoubleQuotes(this string)', correct the spelling of 'str' in parameter name 'str' or remove it entirely if it represents any sort of Hungarian notation. 365 | 366 | 367 | Because the behavior of 'string.EndsWith(string)' could vary based on the current user's locale settings, replace this call in 'UsefulExtension.IsWrappedInDoubleQuotes(this string)' with a call to 'string.EndsWith(string, StringComparison)'. If the result of 'string.EndsWith(string, StringComparison)' will be displayed to the user, such as when sorting a list of items for display in a list box, specify 'StringComparison.CurrentCulture' or 'StringComparison.CurrentCultureIgnoreCase' as the 'StringComparison' parameter. If comparing case-insensitive identifiers, such as file paths, environment variables, or registry keys and values, specify 'StringComparison.OrdinalIgnoreCase'. Otherwise, if comparing case-sensitive identifiers, specify 'StringComparison.Ordinal'. 368 | 369 | 370 | Because the behavior of 'string.StartsWith(string)' could vary based on the current user's locale settings, replace this call in 'UsefulExtension.IsWrappedInDoubleQuotes(this string)' with a call to 'string.StartsWith(string, StringComparison)'. If the result of 'string.StartsWith(string, StringComparison)' will be displayed to the user, such as when sorting a list of items for display in a list box, specify 'StringComparison.CurrentCulture' or 'StringComparison.CurrentCultureIgnoreCase' as the 'StringComparison' parameter. If comparing case-insensitive identifiers, such as file paths, environment variables, or registry keys and values, specify 'StringComparison.OrdinalIgnoreCase'. Otherwise, if comparing case-sensitive identifiers, specify 'StringComparison.Ordinal'. 371 | 372 | 373 | In externally visible method 'UsefulExtension.IsWrappedInDoubleQuotes(this string)', validate parameter 'str' before using it. 374 | 375 | 376 | 377 | 378 | 379 | 380 | In method 'UsefulExtension.RemoveAnyWrappingDoubleQuotes(this string)', correct the spelling of 'str' in parameter name 'str' or remove it entirely if it represents any sort of Hungarian notation. 381 | 382 | 383 | In externally visible method 'UsefulExtension.RemoveAnyWrappingDoubleQuotes(this string)', validate parameter 'str' before using it. 384 | 385 | 386 | 387 | 388 | 389 | 390 | The discrete term 'Whitespace' in member name 'UsefulExtension.SplitOnWhitespace(this string)' should be expressed as a compound word, 'WhiteSpace'. 391 | 392 | 393 | 394 | 395 | 396 | 397 | In method 'UsefulExtension.WrapInDoubleQuotes(this string)', correct the spelling of 'str' in parameter name 'str' or remove it entirely if it represents any sort of Hungarian notation. 398 | 399 | 400 | Because the behavior of 'string.Format(string, object)' could vary based on the current user's locale settings, replace this call in 'UsefulExtension.WrapInDoubleQuotes(this string)' with a call to 'string.Format(IFormatProvider, string, params object[])'. If the result of 'string.Format(IFormatProvider, string, params object[])' will be displayed to the user, specify 'CultureInfo.CurrentCulture' as the 'IFormatProvider' parameter. Otherwise, if the result will be stored and accessed by software, such as when it is persisted to disk or to a database, specify 'CultureInfo.InvariantCulture'. 401 | 402 | 403 | 404 | 405 | 406 | 407 | The discrete term 'Whitespace' in member name 'UsefulExtension.WrapInDoubleQuotesIfContainsWhitespace(this string)' should be expressed as a compound word, 'WhiteSpace'. 408 | 409 | 410 | In method 'UsefulExtension.WrapInDoubleQuotesIfContainsWhitespace(this string)', correct the spelling of 'str' in parameter name 'str' or remove it entirely if it represents any sort of Hungarian notation. 411 | 412 | 413 | 414 | 415 | 416 | 417 | 418 | 419 | 420 | 421 | 422 | 423 | 424 | 425 | 'CommandLineOptionGrouper.IsEndOfOptionsKey(string)' passes 'StringComparison.InvariantCultureIgnoreCase' as the 'StringComparison' parameter to 'string.Equals(string, string, StringComparison)'. To perform a non-linguistic comparison, specify 'StringComparison.Ordinal' or 'StringComparison.OrdinalIgnoreCase' instead. 426 | 427 | 428 | 429 | 430 | 431 | 432 | 433 | 434 | 435 | 436 | 'CommandLineParserEngineMark2.IsEndOfOptionsKey(string)' passes 'StringComparison.InvariantCultureIgnoreCase' as the 'StringComparison' parameter to 'string.Equals(string, string, StringComparison)'. To perform a non-linguistic comparison, specify 'StringComparison.Ordinal' or 'StringComparison.OrdinalIgnoreCase' instead. 437 | 438 | 439 | 440 | 441 | 442 | 443 | 444 | 445 | 446 | 447 | Change 'CommandLineParserResult.AdditionalOptionsFound' to be read-only by removing the property setter. 448 | 449 | 450 | Consider a design where 'CommandLineParserResult.AdditionalOptionsFound' doesn't nest generic type 'IList<KeyValuePair<string, string>>'. 451 | 452 | 453 | 454 | 455 | 456 | 457 | 458 | 459 | Make 'CommandLineParserResult' sealed (a breaking change if this class has previously shipped), implement the method non-explicitly, or implement a new method that exposes the functionality of 'ICommandLineParserResult.Errors.get()' and is visible to derived classes. 460 | 461 | 462 | 463 | 464 | 465 | 466 | 467 | 468 | Change 'CommandLineParserResult.UnMatchedOptions' to be read-only by removing the property setter. 469 | 470 | 471 | The compound word 'UnMatched' in member name 'CommandLineParserResult.UnMatchedOptions' exists as a discrete term. If your usage is intended to be single word, case it as 'Unmatched' or strip the first token entirely if it represents any sort of Hungarian notation. 472 | 473 | 474 | Correct the casing of 'Un' in member name 'CommandLineParserResult.UnMatchedOptions' by changing it to 'UN'. 475 | 476 | 477 | 478 | 479 | 480 | 481 | 482 | 483 | 484 | 485 | 'OptionArgumentParser.IsEndOfOptionsKey(string)' passes 'StringComparison.InvariantCultureIgnoreCase' as the 'StringComparison' parameter to 'string.Equals(string, string, StringComparison)'. To perform a non-linguistic comparison, specify 'StringComparison.Ordinal' or 'StringComparison.OrdinalIgnoreCase' instead. 486 | 487 | 488 | 489 | 490 | 491 | 492 | The 'this' parameter (or 'Me' in Visual Basic) of 'OptionArgumentParser.ParseArguments(IEnumerable<string>, ParsedOption)' is never used. Mark the member as static (or Shared in Visual Basic) or use 'this'/'Me' in the method body or at least one property accessor, if appropriate. 493 | 494 | 495 | In externally visible method 'OptionArgumentParser.ParseArguments(IEnumerable<string>, ParsedOption)', validate parameter 'option' before using it. 496 | 497 | 498 | 499 | 500 | 501 | 502 | 503 | 504 | 505 | 506 | Change 'ParsedOption.AdditionalValues' to return a collection or make it a method. 507 | 508 | 509 | 510 | 511 | 512 | 513 | In externally visible method 'ParsedOption.Equals(ParsedOption)', validate parameter 'other' before using it. 514 | 515 | 516 | 517 | 518 | 519 | 520 | Change 'ParsedOption.Values' to return a collection or make it a method. 521 | 522 | 523 | 524 | 525 | 526 | 527 | 528 | 529 | 530 | 531 | In externally visible method 'ParsedOptionFactory.Create(string)', validate parameter 'rawKey' before using it. 532 | 533 | 534 | 535 | 536 | 537 | 538 | 539 | 540 | 541 | 542 | 543 | 544 | 545 | 546 | 'BoolCommandLineOptionParser.Parse(ParsedOption)' calls 'BoolCommandLineOptionParser.TryParse(ParsedOption, out bool)' but does not explicitly check whether the conversion succeeded. Either use the return value in a conditional statement or verify that the call site expects that the out argument will be set to the default value when the conversion fails. 547 | 548 | 549 | In externally visible method 'BoolCommandLineOptionParser.Parse(ParsedOption)', validate parameter 'parsedOption' before using it. 550 | 551 | 552 | 553 | 554 | 555 | 556 | The 'this' parameter (or 'Me' in Visual Basic) of 'BoolCommandLineOptionParser.TryParse(ParsedOption, out bool)' is never used. Mark the member as static (or Shared in Visual Basic) or use 'this'/'Me' in the method body or at least one property accessor, if appropriate. 557 | 558 | 559 | 560 | 561 | 562 | 563 | 564 | 565 | 566 | 567 | In externally visible method 'DateTimeCommandLineOptionParser.CanParse(ParsedOption)', validate parameter 'parsedOption' before using it. 568 | 569 | 570 | 571 | 572 | 573 | 574 | In externally visible method 'DateTimeCommandLineOptionParser.Parse(ParsedOption)', validate parameter 'parsedOption' before using it. 575 | 576 | 577 | 578 | 579 | 580 | 581 | 582 | 583 | 584 | 585 | In externally visible method 'DoubleCommandLineOptionParser.CanParse(ParsedOption)', validate parameter 'parsedOption' before using it. 586 | 587 | 588 | 589 | 590 | 591 | 592 | In externally visible method 'DoubleCommandLineOptionParser.Parse(ParsedOption)', validate parameter 'parsedOption' before using it. 593 | 594 | 595 | 596 | 597 | 598 | 599 | 600 | 601 | 602 | 603 | In method 'EnumCommandLineOptionParser<TEnum>.EnumCommandLineOptionParser()', replace the call to 'string.ToLowerInvariant()' with String.ToUpperInvariant(). 604 | 605 | 606 | Because the behavior of 'Convert.ToInt32(object)' could vary based on the current user's locale settings, replace this call in 'EnumCommandLineOptionParser<TEnum>.EnumCommandLineOptionParser()' with a call to 'Convert.ToInt32(object, IFormatProvider)'. If the result of 'Convert.ToInt32(object, IFormatProvider)' will be based on input from the user, specify 'CultureInfo.CurrentCulture' as the 'IFormatProvider' parameter. Otherwise, if the result will based on input stored and accessed by software, such as when it is loaded from disk or from a database, specify 'CultureInfo.InvariantCulture'. 607 | 608 | 609 | Because the behavior of 'string.Format(string, object)' could vary based on the current user's locale settings, replace this call in 'EnumCommandLineOptionParser<TEnum>.EnumCommandLineOptionParser()' with a call to 'string.Format(IFormatProvider, string, params object[])'. If the result of 'string.Format(IFormatProvider, string, params object[])' will be displayed to the user, specify 'CultureInfo.CurrentCulture' as the 'IFormatProvider' parameter. Otherwise, if the result will be stored and accessed by software, such as when it is persisted to disk or to a database, specify 'CultureInfo.InvariantCulture'. 610 | 611 | 612 | 613 | 614 | 615 | 616 | In externally visible method 'EnumCommandLineOptionParser<TEnum>.CanParse(ParsedOption)', validate parameter 'parsedOption' before using it. 617 | 618 | 619 | 620 | 621 | 622 | 623 | In method 'EnumCommandLineOptionParser<TEnum>.IsDefined(string)', replace the call to 'string.ToLowerInvariant()' with String.ToUpperInvariant(). 624 | 625 | 626 | 627 | 628 | 629 | 630 | In method 'EnumCommandLineOptionParser<TEnum>.Parse(ParsedOption)', replace the call to 'string.ToLowerInvariant()' with String.ToUpperInvariant(). 631 | 632 | 633 | In externally visible method 'EnumCommandLineOptionParser<TEnum>.Parse(ParsedOption)', validate parameter 'parsedOption' before using it. 634 | 635 | 636 | 637 | 638 | 639 | 640 | 641 | 642 | Replace the term 'Flag' in type name 'EnumFlagCommandLineOptionParser<TEnum>' with an appropriate alternate or remove it entirely. 643 | 644 | 645 | 646 | 647 | 648 | 649 | In method 'EnumFlagCommandLineOptionParser<TEnum>.EnumFlagCommandLineOptionParser()', replace the call to 'string.ToLowerInvariant()' with String.ToUpperInvariant(). 650 | 651 | 652 | Because the behavior of 'Convert.ToInt32(object)' could vary based on the current user's locale settings, replace this call in 'EnumFlagCommandLineOptionParser<TEnum>.EnumFlagCommandLineOptionParser()' with a call to 'Convert.ToInt32(object, IFormatProvider)'. If the result of 'Convert.ToInt32(object, IFormatProvider)' will be based on input from the user, specify 'CultureInfo.CurrentCulture' as the 'IFormatProvider' parameter. Otherwise, if the result will based on input stored and accessed by software, such as when it is loaded from disk or from a database, specify 'CultureInfo.InvariantCulture'. 653 | 654 | 655 | Because the behavior of 'string.Format(string, object)' could vary based on the current user's locale settings, replace this call in 'EnumFlagCommandLineOptionParser<TEnum>.EnumFlagCommandLineOptionParser()' with a call to 'string.Format(IFormatProvider, string, params object[])'. If the result of 'string.Format(IFormatProvider, string, params object[])' will be displayed to the user, specify 'CultureInfo.CurrentCulture' as the 'IFormatProvider' parameter. Otherwise, if the result will be stored and accessed by software, such as when it is persisted to disk or to a database, specify 'CultureInfo.InvariantCulture'. 656 | 657 | 658 | 659 | 660 | 661 | 662 | In method 'EnumFlagCommandLineOptionParser<TEnum>.IsDefined(string)', replace the call to 'string.ToLowerInvariant()' with String.ToUpperInvariant(). 663 | 664 | 665 | 666 | 667 | 668 | 669 | In method 'EnumFlagCommandLineOptionParser<TEnum>.Parse(ParsedOption)', replace the call to 'string.ToLowerInvariant()' with String.ToUpperInvariant(). 670 | 671 | 672 | In externally visible method 'EnumFlagCommandLineOptionParser<TEnum>.Parse(ParsedOption)', validate parameter 'parsedOption' before using it. 673 | 674 | 675 | 676 | 677 | 678 | 679 | 680 | 681 | 682 | 683 | In externally visible method 'Int32CommandLineOptionParser.CanParse(ParsedOption)', validate parameter 'parsedOption' before using it. 684 | 685 | 686 | 687 | 688 | 689 | 690 | In externally visible method 'Int32CommandLineOptionParser.Parse(ParsedOption)', validate parameter 'parsedOption' before using it. 691 | 692 | 693 | 694 | 695 | 696 | 697 | 698 | 699 | 700 | 701 | In externally visible method 'Int64CommandLineOptionParser.CanParse(ParsedOption)', validate parameter 'parsedOption' before using it. 702 | 703 | 704 | 705 | 706 | 707 | 708 | In externally visible method 'Int64CommandLineOptionParser.Parse(ParsedOption)', validate parameter 'parsedOption' before using it. 709 | 710 | 711 | 712 | 713 | 714 | 715 | 716 | 717 | 718 | 719 | Change 'List<T>' in 'ListCommandLineOptionParser<T>.Parse(ParsedOption)' to use Collection<T>, ReadOnlyCollection<T> or KeyedCollection<K,V> 720 | 721 | 722 | 723 | 724 | 725 | 726 | 727 | 728 | 729 | 730 | In externally visible method 'NullableCommandLineOptionParser<TNullableType>.Parse(ParsedOption)', validate parameter 'parsedOption' before using it. 731 | 732 | 733 | 734 | 735 | 736 | 737 | 738 | 739 | 740 | 741 | Because the behavior of 'string.Format(string, object)' could vary based on the current user's locale settings, replace this call in 'NullableEnumCommandLineOptionParser<TEnum>.NullableEnumCommandLineOptionParser(ICommandLineOptionParserFactory)' with a call to 'string.Format(IFormatProvider, string, params object[])'. If the result of 'string.Format(IFormatProvider, string, params object[])' will be displayed to the user, specify 'CultureInfo.CurrentCulture' as the 'IFormatProvider' parameter. Otherwise, if the result will be stored and accessed by software, such as when it is persisted to disk or to a database, specify 'CultureInfo.InvariantCulture'. 742 | 743 | 744 | 745 | 746 | 747 | 748 | In externally visible method 'NullableEnumCommandLineOptionParser<TEnum>.Parse(ParsedOption)', validate parameter 'parsedOption' before using it. 749 | 750 | 751 | 752 | 753 | 754 | 755 | 756 | 757 | 758 | 759 | In externally visible method 'StringCommandLineOptionParser.CanParse(ParsedOption)', validate parameter 'parsedOption' before using it. 760 | 761 | 762 | 763 | 764 | 765 | 766 | In externally visible method 'StringCommandLineOptionParser.Parse(ParsedOption)', validate parameter 'parsedOption' before using it. 767 | 768 | 769 | 770 | 771 | 772 | 773 | 774 | 775 | 776 | 777 | 'UriCommandLineOptionParser.CanParse(ParsedOption)' creates a new instance of 'Uri' which is never used. Pass the instance as an argument to another method, assign the instance to a variable, or remove the object creation if it is unnecessary. 778 | 779 | 780 | In externally visible method 'UriCommandLineOptionParser.CanParse(ParsedOption)', validate parameter 'parsedOption' before using it. 781 | 782 | 783 | 784 | 785 | 786 | 787 | In externally visible method 'UriCommandLineOptionParser.Parse(ParsedOption)', validate parameter 'parsedOption' before using it. 788 | 789 | 790 | 791 | 792 | 793 | 794 | 795 | 796 | 797 | 798 | 799 | 800 | 801 | 802 | In externally visible method 'NoDuplicateOptionValidator.Validate(ICommandLineOption)', validate parameter 'commandLineOption' before using it. 803 | 804 | 805 | 806 | 807 | 808 | 809 | 810 | 811 | 812 | 813 | Method 'OptionNameValidator.ValidateLongName(string)' passes a literal string as parameter 'message' of a call to 'OptionNameValidator.ThrowInvalid(string, string)'. Retrieve the following string(s) from a resource table instead: "Long names must be longer than a single character. Single characters are reserve...". 814 | 815 | 816 | 817 | 818 | 819 | 820 | Method 'OptionNameValidator.ValidateShortAndLongName(string, string)' passes a literal string as parameter 'message' of a call to 'OptionNameValidator.ThrowInvalid(string, string)'. Retrieve the following string(s) from a resource table instead: "A short or long name must be provided.". 821 | 822 | 823 | 824 | 825 | 826 | 827 | Method 'OptionNameValidator.ValidateShortName(string)' passes a literal string as parameter 'message' of a call to 'OptionNameValidator.ThrowInvalid(string, string)'. Retrieve the following string(s) from a resource table instead: "Short names must be a single character only.". 828 | Method 'OptionNameValidator.ValidateShortName(string)' passes a literal string as parameter 'message' of a call to 'OptionNameValidator.ThrowInvalid(string, string)'. Retrieve the following string(s) from a resource table instead: "The character \', \' is not valid for a short name.". 829 | 830 | 831 | 832 | 833 | 834 | 835 | Method 'OptionNameValidator.VerifyDoesNotContainsReservedChar(string)' passes a literal string as parameter 'message' of a call to 'OptionNameValidator.ThrowInvalid(string, string)'. Retrieve the following string(s) from a resource table instead: "The character \', \' is not valid within a short or long name.". 836 | 837 | 838 | 839 | 840 | 841 | 842 | 843 | 844 | 845 | 846 | 847 | 848 | 849 | 850 | Array fields should not be read only 851 | Read-only fields that reference arrays might not give the intended effect. Setting a field which references an array to read-only prevents the value of the field from being changed. Note that elements in the array can be changed. You can ignore this violation if protecting the contents of the array is not a concern. 852 | Either replace {0} with a strongly typed collection that cannot be changed, or replace the public field with a method that returns a clone of a private array. 853 | 854 | http://msdn.microsoft.com/library/ms182299(VS.100).aspx 855 | [none] 856 | CriticalWarning 857 | 858 | 859 | 860 | Assemblies should have valid strong names 861 | Either the assembly has no strong name, an invalid one, or the strong name is valid only because of the computer configuration. The assembly should not be deployed in this state. The most common causes of this are: 1) The assembly's contents were modified after it was signed. 2) The signing process failed. 3) The assembly was delay-signed. 4) A registry key existed that allowed the check to pass (where it would not have otherwise). 862 | Sign {0} with a strong name key. 863 | 864 | http://msdn.microsoft.com/library/ms182127(VS.100).aspx 865 | [none] 866 | CriticalError 867 | 868 | 869 | 870 | Avoid namespaces with few types 871 | A namespace should generally have more than five types. 872 | Consider merging the types defined in '{0}' with another namespace. 873 | 874 | http://msdn.microsoft.com/library/ms182130(VS.100).aspx 875 | [none] 876 | Warning 877 | 878 | 879 | 880 | Collection properties should be read only 881 | Properties that return collections should be read-only so that users cannot entirely replace the backing store. Users can still modify the contents of the collection by calling relevant methods on the collection. Note that the XmlSerializer class has special support for deserializing read-only collections. See the XmlSerializer overview for more information. 882 | Change {0} to be read-only by removing the property setter. 883 | 884 | http://msdn.microsoft.com/library/ms182327(VS.100).aspx 885 | [none] 886 | Warning 887 | 888 | 889 | 890 | Compound words should be cased correctly 891 | Avoid creating compound words from terms which exist in the dictionary as discrete terms. Do not create a compound word such as 'StopWatch' or 'PopUp'. These terms are recognized in the dictionary and should be cased as 'Stopwatch' and 'Popup'. 892 | The discrete term '{0}' in member name {1} should be expressed as a compound word, '{2}'. 893 | The compound word '{0}' in member name {1} exists as a discrete term. If your usage is intended to be single word, case it as '{2}' or strip the first token entirely if it represents any sort of Hungarian notation. 894 | 895 | http://msdn.microsoft.com/library/bb264474(VS.100).aspx 896 | [none] 897 | Error 898 | 899 | 900 | 901 | Do not pass literals as localized parameters 902 | Literal strings that are embedded in source code are difficult to localize. Avoid passing literal strings as arguments in circumstances where a localized string is generally expected. 903 | Method {0} passes a literal string as parameter '{1}' of a call to {2}. Retrieve the following string(s) from a resource table instead: {3}. 904 | RuleOwner 905 | http://msdn.microsoft.com/library/ms182187(VS.100).aspx 906 | 907 | Warning 908 | 909 | 910 | 911 | Do not expose generic lists 912 | Do not expose List<T> in object models. Use Collection<T>, ReadOnlyCollection<T> or KeyedCollection<K,V> instead. List<T> is meant to be used from implementation, not in object model API. List<T> is optimized for performance at the cost of long term versioning. For example, if you return List<T> to the client code, you will not ever be able to receive notifications when client code modifies the collection. 913 | Change {0} in {1} to use Collection<T>, ReadOnlyCollection<T> or KeyedCollection<K,V> 914 | 915 | http://msdn.microsoft.com/library/ms182142(VS.100).aspx 916 | [none] 917 | Error 918 | 919 | 920 | 921 | Do not ignore method results 922 | The result of methods that return new instances of strings should be assigned to a variable and subsequently used. If the result of a method that creates a new object, such as String.ToLower(), is not assigned to a variable, the call is wasted. 923 | {0} creates a new instance of {1} which is never used. Pass the instance as an argument to another method, assign the instance to a variable, or remove the object creation if it is unnecessary. 924 | {0} calls {1} but does not explicitly check whether the conversion succeeded. Either use the return value in a conditional statement or verify that the call site expects that the out argument will be set to the default value when the conversion fails. 925 | 926 | http://msdn.microsoft.com/library/ms182273(VS.100).aspx 927 | [none] 928 | Warning 929 | 930 | 931 | 932 | Do not nest generic types in member signatures 933 | Avoid API that require users to instantiate a generic type with another generic type as type argument. The syntax gets too complex. 934 | Consider a design where {0} doesn't nest generic type {1}. 935 | 936 | http://msdn.microsoft.com/library/ms182144(VS.100).aspx 937 | [none] 938 | CriticalError 939 | 940 | 941 | 942 | Identifiers should be cased correctly 943 | Type, namespace, and member identifiers are Pascal-cased. Parameter identifiers are camel-cased. Two letter acronyms within these identifiers should be upper-cased, for example, use System.IO instead of System.Io. Acronyms of three or more letters should be Pascal-cased, for example, use System.Xml instead of System.XML. The pascal-casing convention capitalizes the first letter of each word, as in BackColor. The camel-casing convention formats the first letter of the first word in lowercase and capitalizes the first letter of all subsequent words, as in backgroundColor. Although it may be common practice for some two letter acronyms to not be fully capitalized, violations of this rule should not be excluded for this reason. For example, 'DbConnection', is common but incorrect; use DBConnection. A violation of this rule might be required for compatibility with existing, non-managed symbol schemes. In general, however, these symbols should not be visible outside the assembly that uses them. 944 | Correct the casing of '{0}' in member name {1} by changing it to '{2}'. 945 | 946 | http://msdn.microsoft.com/library/ms182240(VS.100).aspx 947 | [none] 948 | Error 949 | 950 | 951 | 952 | Identifiers should be spelled correctly 953 | The individual words that make up an identifier should not be abbreviated and should be spelled correctly. If this rule generates a false positive on a term that should be recognized, add the word to the FxCop custom dictionary. 954 | In method {0}, correct the spelling of '{1}' in parameter name {2} or remove it entirely if it represents any sort of Hungarian notation. 955 | Correct the spelling of '{0}' in namespace name '{1}'. 956 | 957 | http://msdn.microsoft.com/library/bb264492(VS.100).aspx 958 | [none] 959 | CriticalWarning 960 | 961 | 962 | 963 | Identifiers should not match keywords 964 | Identifiers which conflict with reserved language keywords should be avoided. Using a reserved keyword as an identifier makes it harder for consumers in other languages to use your API. 965 | Rename virtual/interface member {0} so that it no longer conflicts with the reserved language keyword '{1}'. Using a reserved keyword as the name of a virtual/interface member makes it harder for consumers in other languages to override/implement the member. 966 | 967 | http://msdn.microsoft.com/library/ms182248(VS.100).aspx 968 | [none] 969 | Error 970 | 971 | 972 | 973 | Implement standard exception constructors 974 | Multiple constructors are required to correctly implement a custom exception. Missing constructors can make your exception unusable in certain scenarios. For example, the serialization constructor is required for handling exceptions in XML Web services. 975 | Change the accessibility of {0} to {1}. 976 | Add the following constructor to {0}: {1}. 977 | 978 | http://msdn.microsoft.com/library/ms182151(VS.100).aspx 979 | [none] 980 | Error 981 | 982 | 983 | 984 | Interface methods should be callable by child types 985 | Explicit method implementations are defined with private accessibility. Classes that derive from classes with explicit method implementations and choose to re-declare them on the class will not be able to call into the base class implementation unless the base class has provided an alternate method with appropriate accessibility. When overriding a base class method that has been hidden by explicit interface implementation, in order to call into the base class implementation, a derived class must cast the base pointer to the relevant interface. When calling through this reference, however, the derived class implementation will actually be invoked, resulting in recursion and an eventual stack overflow. 986 | Make {0} sealed (a breaking change if this class has previously shipped), implement the method non-explicitly, or implement a new method that exposes the functionality of {1} and is visible to derived classes. 987 | 988 | http://msdn.microsoft.com/library/ms182153(VS.100).aspx 989 | [none] 990 | Error 991 | 992 | 993 | 994 | Literals should be spelled correctly 995 | This rule parses the literal string into words, tokenizing compound words, and checks the spelling of each word/token. 996 | Correct the spelling of the unrecognized token '{0}' in the literal '{1}'. 997 | RuleOwner 998 | http://msdn.microsoft.com/library/bb264488(VS.100).aspx 999 | 1000 | Warning 1001 | 1002 | 1003 | 1004 | Mark ISerializable types with SerializableAttribute 1005 | The System.Runtime.Serialization.ISerializable interface allows the type to customize its serialization, while the Serializable attribute enables the runtime to recognize the type as being serializable. 1006 | Add [Serializable] to {0} as this type implements ISerializable. 1007 | 1008 | http://msdn.microsoft.com/library/ms182350(VS.100).aspx 1009 | [none] 1010 | Warning 1011 | 1012 | 1013 | 1014 | Mark members as static 1015 | Methods which do not access instance data or call instance methods can be marked as static (Shared in Visual Basic). After doing so, the compiler will emit non-virtual call sites to these members which will prevent a check at runtime for each call that ensures the current object pointer is non-null. This can result in a measurable performance gain for performance-sensitive code. In some cases, the failure to access the current object instance represents a correctness issue. 1016 | The 'this' parameter (or 'Me' in Visual Basic) of {0} is never used. Mark the member as static (or Shared in Visual Basic) or use 'this'/'Me' in the method body or at least one property accessor, if appropriate. 1017 | 1018 | http://msdn.microsoft.com/library/ms245046(VS.100).aspx 1019 | [none] 1020 | Warning 1021 | 1022 | 1023 | 1024 | Normalize strings to uppercase 1025 | Strings should be normalized to upper-case. 1026 | In method {0}, replace the call to {1} with String.ToUpperInvariant(). 1027 | 1028 | http://msdn.microsoft.com/library/bb386042(VS.100).aspx 1029 | [none] 1030 | Error 1031 | 1032 | 1033 | 1034 | Parameter names should match base declaration 1035 | For usability reasons, parameter names in overridden methods should match those of the base declaration. 1036 | In member {0}, change parameter name {1} to {2} in order to match the identifier as it has been declared in {3}. 1037 | 1038 | http://msdn.microsoft.com/library/ms182251(VS.100).aspx 1039 | [none] 1040 | Error 1041 | 1042 | 1043 | 1044 | Parameter names should not match member names 1045 | Parameter names should be distinct from member names. 1046 | Change either member or parameter name {0} so that one differs from the other. 1047 | 1048 | http://msdn.microsoft.com/library/ms182252(VS.100).aspx 1049 | [none] 1050 | Error 1051 | 1052 | 1053 | 1054 | Properties should not return arrays 1055 | Properties that return arrays are prone to code inefficiencies. Consider using a collection or making this a method. See the design guidelines for more information. 1056 | Change {0} to return a collection or make it a method. 1057 | 1058 | http://msdn.microsoft.com/library/0fss9skc(VS.100).aspx 1059 | [none] 1060 | Warning 1061 | 1062 | 1063 | 1064 | Specify IFormatProvider 1065 | If an overload exists that takes an IFormatProvider argument, it should always be called in favor of an overload that does not. Some methods in the runtime convert a value to or from a string representation and take a string parameter that contains one or more characters, called format specifiers, which indicate how the value is to be converted. If the meaning of the format specifier varies by culture, a formatting object supplies the actual characters used in the string representation. In scenarios where sorting and comparison behavior should never change between cultures, specify CultureInfo.InvariantCulture, otherwise, specify CultureInfo.CurrentCulture. 1066 | Because the behavior of {0} could vary based on the current user's locale settings, replace this call in {1} with a call to {2}. If the result of {2} will be based on input from the user, specify {3} as the 'IFormatProvider' parameter. Otherwise, if the result will based on input stored and accessed by software, such as when it is loaded from disk or from a database, specify {4}. 1067 | Because the behavior of {0} could vary based on the current user's locale settings, replace this call in {1} with a call to {2}. If the result of {2} will be displayed to the user, specify {3} as the 'IFormatProvider' parameter. Otherwise, if the result will be stored and accessed by software, such as when it is persisted to disk or to a database, specify {4}. 1068 | 1069 | http://msdn.microsoft.com/library/ms182190(VS.100).aspx 1070 | [none] 1071 | Error 1072 | 1073 | 1074 | 1075 | Specify StringComparison 1076 | If an overload exists that takes a StringComparison argument, it should always be called in favor of an overload that does not. 1077 | Because the behavior of {0} could vary based on the current user's locale settings, replace this call in {1} with a call to {2}. If the result of {2} will be displayed to the user, such as when sorting a list of items for display in a list box, specify 'StringComparison.CurrentCulture' or 'StringComparison.CurrentCultureIgnoreCase' as the 'StringComparison' parameter. If comparing case-insensitive identifiers, such as file paths, environment variables, or registry keys and values, specify 'StringComparison.OrdinalIgnoreCase'. Otherwise, if comparing case-sensitive identifiers, specify 'StringComparison.Ordinal'. 1078 | 1079 | http://msdn.microsoft.com/library/bb386080(VS.100).aspx 1080 | [none] 1081 | Error 1082 | 1083 | 1084 | 1085 | Use ordinal StringComparison 1086 | For non-linguistic comparisons, StringComparison.Ordinal or StringComparison.OrdinalIgnoreCase should be used instead of the linguistically-sensitive StringComparison.InvariantCulture. 1087 | {0} passes '{1}' as the 'StringComparison' parameter to {2}. To perform a non-linguistic comparison, specify 'StringComparison.Ordinal' or 'StringComparison.OrdinalIgnoreCase' instead. 1088 | 1089 | http://msdn.microsoft.com/library/bb385972(VS.100).aspx 1090 | [none] 1091 | Error 1092 | 1093 | 1094 | 1095 | Use preferred terms 1096 | Use preferred terms over deprecated alternates. 1097 | Replace the term '{0}' in type name {1} with an appropriate alternate or remove it entirely. 1098 | 1099 | http://msdn.microsoft.com/library/ms182258(VS.100).aspx 1100 | [none] 1101 | Error 1102 | 1103 | 1104 | 1105 | Validate arguments of public methods 1106 | All reference arguments passed to externally visible methods should be checked against null (Nothing in VB). If appropriate, throw a System.ArgumentNullException when the argument is null. 1107 | In externally visible method {0}, validate parameter '{1}' before using it. 1108 | RuleOwner 1109 | http://msdn.microsoft.com/library/ms182182(VS.100).aspx 1110 | 1111 | Warning 1112 | 1113 | 1114 | 1115 | 1116 | Category 1117 | Certainty 1118 | Collapse All 1119 | Check Id 1120 | Error 1121 | error(s) 1122 | Expand All 1123 | Help 1124 | Line 1125 | message(s) 1126 | [Location not stored in Pdb] 1127 | Project 1128 | Resolution 1129 | Rule 1130 | Rule File 1131 | Rule Description 1132 | Source 1133 | Status 1134 | Target 1135 | Warning 1136 | warning(s) 1137 | Code Analysis Report 1138 | 1139 | 1140 | -------------------------------------------------------------------------------- /source/packages/FluentCommandLineParser.1.4.3/lib/net35/FluentCommandLineParser.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/woanware/wmi-parser/754ce11d096e5b01ef496c02e4df46ffccd4dcf8/source/packages/FluentCommandLineParser.1.4.3/lib/net35/FluentCommandLineParser.dll -------------------------------------------------------------------------------- /source/packages/FluentCommandLineParser.1.4.3/lib/net35/FluentCommandLineParser.pdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/woanware/wmi-parser/754ce11d096e5b01ef496c02e4df46ffccd4dcf8/source/packages/FluentCommandLineParser.1.4.3/lib/net35/FluentCommandLineParser.pdb -------------------------------------------------------------------------------- /source/wmi-parser.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {183B0BCC-55AE-4336-BE27-8A9A57A153AF} 8 | Exe 9 | wmi 10 | wmi-parser 11 | v4.7.2 12 | 512 13 | true 14 | true 15 | 16 | 17 | x64 18 | true 19 | full 20 | false 21 | bin\Debug\ 22 | DEBUG;TRACE 23 | prompt 24 | 4 25 | 26 | 27 | x64 28 | pdbonly 29 | true 30 | bin\Release\ 31 | TRACE 32 | prompt 33 | 4 34 | 35 | 36 | 37 | packages\CsvHelper.9.2.3\lib\net45\CsvHelper.dll 38 | 39 | 40 | packages\FluentCommandLineParser.1.4.3\lib\net35\FluentCommandLineParser.dll 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /source/wmi-parser.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 15 4 | VisualStudioVersion = 15.0.28010.2046 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "wmi-parser", "wmi-parser.csproj", "{183B0BCC-55AE-4336-BE27-8A9A57A153AF}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {183B0BCC-55AE-4336-BE27-8A9A57A153AF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {183B0BCC-55AE-4336-BE27-8A9A57A153AF}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {183B0BCC-55AE-4336-BE27-8A9A57A153AF}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {183B0BCC-55AE-4336-BE27-8A9A57A153AF}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | GlobalSection(ExtensibilityGlobals) = postSolution 23 | SolutionGuid = {9A80B687-C5F2-4BF9-BF7E-6ACB251A07C4} 24 | EndGlobalSection 25 | EndGlobal 26 | --------------------------------------------------------------------------------