/Community

A Support Community for SubMain Products
in Search
Welcome to SubMain Community Sign in | Join | Help

Tutorials

  • CodeItRight.Cmd.exe Command Line Options

    CodeItRight.Cmd is the command-line companion to the CodeIt.Right application. Like CodeIt.Right, CodeItRight.Cmd analyzes source code and reports violations, such as possible design, performance, and security issues. CodeItRight.Cmd can be used as a stand-alone tool or added to automated build processes. 

    The following are the command line parameters that are supported by SubMain.CodeItRight.Cmd.exe ; Parameter values are not case sensitive.

    /Solution  - (Required*) - full file name of the solution to load (*.sln file) (*) This parameter is not required if /Project parameter specified.
     
    /Project   - (Required*) - full file name of the project to load (*.csproj or *.vbproj file) (*) This parameter is not required if /Solution parameter specified.

    /Out  - (Required) - full name of the xml report output file.

    /OutXSL  - (Optional) - full name of the xsl file to override the default xsl.

    /CRData  - (Optional) - full name of the CodeIt.Right .crdata file. When specified, CodeItRight.Cmd will use the exclusion list (violations, rules and files) saved using the Visual Studio version of CodeIt.Right.

    /Profile  - (Optional) - name of the User Profile that defines active rule set for the analysis. When omitted, the buil-in profile is used.

    /Quiet - (Optional) - disables console output.
     
    /Help  - display list of command line parameters.

    Example:

    SubMain.CodeItRight.Cmd.exe /Solution:"C:\MyProjects\MyProject\MyProject.sln"
    /Out:"C:\MyProjects\MyProject\MyProject.CIR.Output.xml"
    /CRData:"C:\MyProjects\MyProject\MyProject.crdata" /Profile:"My Profile"

    CodeItRight.Cmd Error Codes

    0x0No errors
    0x1Command Line Switch Error
    0x2Command Line Argument Error
    0x4Initialization Error
    0x8Analysis Error
    0x10Output Error
    0x20Unknown Error
  • Tutorial: Creating Custom Rules

    The best part about CodeIt.Right is that you are not limited to just the rule libraries included into the box. You can easily define your own (custom) rules. What makes this possible is the "CodeIt.Right SDK". The SDK documentation is available online at http://submain.com/codeit.right/sdk/ as well as locally as part of your CodeIt.Right help file.

    In this tutorial we will create "Use Certain Suffixes For Derived Types" rule. We will

    • Create Custom Rule Template using Wizard that CodeIt.Right adds to Visual Studio
    • Implement set of methods and properties that will find and correct violations of the rule
    • Define Configurable Properties for the rule, so the users will be able to create instances of the rule and tweak it to their needs
    • Deploy the new rule

    Create Custom Rule Template Using Wizard

    1. Open Visual Studio

    2. In the menu bar, click File, and then click New Project

    3. In the New Project dialog box, in the Project Types pane, select CodeIt.Right Projects if that option is not already selected.

    4. In the Templates pane, select the template for the appropriate programming language (Visual Basic or Visual C#). The custom rule in the examples uses Visual Basic.

    5. Complete the Name, Location, and Solution fields for the custom rule.

    6. Click OK. The New Rule Wizard dialog box appears.

    7. In the New Rule Wizard dialog box, complete as many of the fields as possible. Fields that have a red asterisk to the right are required. Click Next.

    8. Select the options to determine the scope for the custom rule. To select or deselect all the options, select All. Click Next.

    9. Select the targets for the custom rule. When done, click Finish.

    The status bar at the bottom of the Visual Studio window displays the progress of the creation of the custom rule.

    Edit the Generated Template

    After a custom rule template is created, you can edit it in the Solution Explorer. You can edit template information, the content generated by the New Rule Wizard, and implement code of the Check and Correct methods.

    1. Double-click the rule in Soultion Explorer to edit it. The generated regions of the rule are collapsed by default.

    2. Expand the Wizard Generated Code region to review the code generated based on options selected in the New Rule Wizard. You can edit the options if necessary. Note that the rule's ID is automatically generated GUID - you can edit it as well but make sure your ID is not equal to any of the built-in CodeIt.Right rules or even better your rule ID doesn't follow CodeIt.Right internal ID schema.

      #Region "Wizard Generated Code"
      
      #Region "Data Entered On Wizard form"
      
          Private Const InputID As String = "0500daf7-f2a0-4549-b90e-bd8f6d515bb5"
          Private Const InputName As String = "UseCertainSuffixesForDerivedTypes"
          Private Const InputTitle As String = "Use Certain Suffixes For Derived Types"
          Private Const InputSeverity As SeverityLevel = SeverityLevel.Warning
          Private Const InputScopes As RuleScopes = _
            RuleScopes.Public or RuleScopes.ProtectedInternal or RuleScopes.Private or RuleScopes.Abstract or RuleScopes.Sealed _
            or RuleScopes.Readonly or RuleScopes.Virtual or RuleScopes.Override or RuleScopes.Extern or RuleScopes.Unsafe _
            or RuleScopes.SpecialName or RuleScopes.Const or RuleScopes.Volatile or RuleScopes.WriteOnly _
            or RuleScopes.WithEvents or RuleScopes.Default
          Private Const InputAuthor As String = "SubMain Team"
          Private Const InputEmail As String = "support@submain.com"
          Private Const InputUrl As String = ""
          Private Const InputAvailableTargets As RuleTargets = RuleTargets.Class
          Private Const InputViolationDescription As String = ""
      
      #End Region
      
      #Region "Constructor"
      
          Public Sub New()
              Me.Name = InputName
              Me.Title = InputTitle
              Me.Severity = InputSeverity
              Me.Targets = Me.AvailableTargets
              Me.Scopes = InputScopes
          End Sub
      
      #End Region
      
          Public Overrides ReadOnly Property ID As String
              Get
                  Return InputID
              End Get
          End Property
      
          Public Overrides ReadOnly Property AvailableTargets As RuleTargets
              Get
                  Return InputAvailableTargets
              End Get
          End Property
      
          Public Overrides ReadOnly Property Author As String
              Get
                  Return InputAuthor
              End Get
          End Property
      
          Public Overrides ReadOnly Property Email As String
              Get
                  Return InputEmail
              End Get
          End Property
      
          Public Overrides ReadOnly Property Url As String
              Get
                  Return InputUrl
              End Get
          End Property
      
          Public Overrides ReadOnly Property ViolationDescription As String
              Get
                  Return InputViolationDescription
              End Get
          End Property
      
          Public Overloads Function Correct(ByVal correctionOptionIndex as Integer) As Boolean
              MyBase.Correct(correctionOptionIndex)
      
              Select Case correctionOptionIndex
      
                  Case Else
              End Select
      
              Return False
          End Function
      
      #End Region
      
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
      37
      38
      39
      40
      41
      42
      43
      44
      45
      46
      47
      48
      49
      50
      51
      52
      53
      54
      55
      56
      57
      58
      59
      60
      61
      62
      63
      64
      65
      66
      67
      68
      69
      70
      71
      72
      73
      74
      75
      76
      77
      78
      79
      80
      81
      

    3. In the Template to be populated by rule author region, edit the AutoCorrectionOptions property to establish all the options for automatic correction of violations to the rule. Each option is added to the drop-down list in the Action column when code is analyzed. The GetCorrect0Name will be implemented in the next bullet.

      Public Overrides ReadOnly Property AutoCorrectionOptions As String()
      
          Get
      
              If (MyBase._userCorrectOptions.Count = 0) Then
      
                  ' Get title of the correction option
                  Dim text As String = Me.GetCorrect0Name
      
                  If ([text].Length > 0) Then
      
                      ' Add to the list of available options
                      MyBase._userCorrectOptions.Add([text])
      
                  End If
      
              End If
      
              Return MyBase.AutoCorrectionOptions
      
          End Get
      
      End Property
      
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      

    4. In the Template to be populated by rule author region, edit the Correction method to establish how violations to the rule are corrected. In the example below, the correct suffix is added to the code element. The new name is then checked using helper function NamingRuleUtilities.FixForUniqueName to make sure it is unique in the solution. If not, the name is further modified so that it is unique. SuffixToCheck is a configurable property that we will define later in this tutorial.

      Private Function GetCorrect0Name() As String
      
          Dim baseName As String = String.Empty
      
          If (Not MyBase.Element Is Nothing) Then
      
              Dim info As ICodeElementInfo = MyBase.Element.ToCodeElementInfo
      
              If (Not info Is Nothing) Then
      
                  ' Get the code element name
                  Dim displayName As String = info.DisplayName
      
                  ' Add the correct suffix
                  If ((Not Me.SuffixToCheck Is Nothing) AndAlso (Me.SuffixToCheck.Length > 0)) Then
                      baseName = (displayName & Me.SuffixToCheck)
                  End If
      
              End If
          End If
      
          ' Make sure the new name is unique
          Return NamingRuleUtilities.FixForUniqueName(baseName, MyBase.Element)
      
      End Function
      
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      

    5. In the Template to be populated by rule author region, edit the Check method to establish violations to the rule are found. In the example below, each appropriate code element is checked for the correct suffix. If the element does not include the correct suffix, it is flagged as a violation. MustImplement is another configurable property defined later in the tutorial. Method ITypeInfo.IsAssignableFrom returns True if the code element derived from the type stored in MustImplement. Helper function NamingRuleUtilities.HasSuffix returns True is code element has the suffix, False otherwise.

      Public Overrides Function Check(ByVal element As IElementInfo) As Boolean
      
          If (Not element Is Nothing) Then
      
              Dim info As ICodeElementInfo = element.ToCodeElementInfo
      
              If (Not info Is Nothing) Then
      
                  ' Get the code element name
                  Dim displayName As String = info.DisplayName
      
                  ' If configurable properties SuffixToCheck and MustImplement have values
                  If (((Not Me.SuffixToCheck Is Nothing) AndAlso (Me.SuffixToCheck.Length > 0)) _
                     AndAlso ((Not Me.MustImplement Is Nothing) AndAlso (Me.MustImplement.Length > 0))) Then
      
                      Dim info2 As ITypeInfo = TryCast(info, ITypeInfo)
      
                      ' If element derives from the type (MustImplement) and doesn't have correct suffix (SuffixToCheck)
                      If (((Not info2 Is Nothing) AndAlso info2.IsAssignableFrom(Me.MustImplement)) _
                         AndAlso Not NamingRuleUtilities.HasSuffix(displayName, Me.SuffixToCheck)) Then
      
                          ' Flag the violation
                          Return True
      
                      End If
      
                  End If
      
              End If
      
          End If
      
          Return False
      
      End Function
      
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      

    Configurable Properties

    Configurable Properties are flexible mechanism that allows to develop rules that can be customized in user profiles (rule instances). They must be marked with attribute <ConfigurableProperty>.

    For our rule we need two configurable properties -

    • MustImplement - will filter and only run the rest of the rule against code elements that derive from the type assigned in this property
    • SuffixToCheck - will allow to define for each rule instance suffix to be that the code element derived from MustImplement should have

    • <ConfigurableProperty, Description("Type should implement the specified type or interface")> _
          Public Property MustImplement As String
      
              Get
                  Return Me._mustImplement
              End Get
      
              Set(ByVal value As String)
                  Me._mustImplement = value
              End Set
      
          End Property
      
      <ConfigurableProperty, Description("Certain Suffix to be checked")> _
          Public Property SuffixToCheck As String
      
              Get
                  Return Me._suffixToCheck
              End Get
      
              Set(ByVal value As String)
                  Me._suffixToCheck = value
              End Set
      
          End Property
      
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      

    Here is how properties are configured for a specific instance of the rule we developed in this tutorial - "Exception class name must have 'Exception' suffix" (click the image for full size):

    Adding another rule to the same project

    At this point of the tutorial we have one custom rule implemented in the project (library). If you want to add another rule or more to the library, you need to right-click project in the Solution Explorer, select Add New Item and pick Custom Rule Class under CodeIt.Right Items - this will start New Rule Wizard.

    Build and Deploy new rule

    Our rule is now ready to be deployed.

    1. Build your custom rule project
    2. Copy the resulting .dll assembly into the <CodeIt.Right installation>\Rules directory (typically Program Files\SubMain\CodeIt.Right\Rules)
    3. Add a new instance of the new rule to your user profile. See How to add rule to User Profile.

    Note: You don't need to close Visual Studio when you deploy new or updated rule library. CodeIt.Right picks up the rule library changes every time you analyze code or open Profile Editor.

    Where do I find samples?

    Your best source for rule examples is CodeIt.Right's own rule library (see the <CodeIt.Right installation>\Rules directory). As of this post we have implemented 75+ rule classes with 100+ rule instances in the detault profile. Feel free to explore what we've got using Lutz Roeder's wonderful Reflector and learn what's inside of each rule.

    Keep an eye on is our community Custom Rule Repository - it will grow as users develop and share their rules. This is also the place where we post our complete sample rule projects.

    Further Reading and Resources

    1. CodeIt.Right SDK Documentation
    2. CodeIt.Right Tutorials
    3. How to create own Profile
    4. How to add rule to User Profile
    5. Defining ViolationDescription and CorrectionDescription properties (to be published)
    6. Built-in API helper functions
    7. Custom Rule Repository
    8. FxCop rule mapping (to be published)
    9. Using SuppressMessage Attribute (to be published)
    10. Top 10 most useful API helper functions explained (to be published)