Can someone post a Visual Studio macro which goes through all C# source files in a project and adds a file banner? Extra credit if it works for any type of source file (.cs, .xaml, etc).
Wow--great answer. Too bad the OP doesn't seem to grok Google.
Onorio Catenacci
2009-01-06 02:13:39
Thanks for the link. Onorio, I did try google but used the word "banner" instead of "header"... which returns entirely different results. Don't know why, I've always called them banners. Of course now because of this post, using the word "banner" returns this very post!
DSO
2009-01-06 02:28:10
+1
A:
Here is the jist of it. No, I have not debugged this, that is an excercise for the reader. And, this is done off the top of my head. (Except the File commenter...That's a real Macro that I use).
function CommentAllFiles
option explicit
Dim ActiveProjectFullName
Dim dte80 As EnvDTE80.Solution2
ActiveProjectFullName = dte80.Projects.Item(0).FullName
If ActiveProjectFullName = "" Then
MsgBox("No project loaded!")
Exit Sub
End If
Err.Number = 0
doc.Open(ActiveProjectFullName, "Text", True)
If Err.Number <> 0 Then
MsgBox("Open " + ActiveProjectFullName + " failed: " & Hex(Err.Number))
Exit Sub
End If
ActiveDocument.Goto(1, 1, vsMovementOptions.vsMovementOptionsMove)
' Build search string
Dim SearchString
Dim vsFindOptionsValue As Integer
SearchString = "^SOURCE=.*" + dn + "$"
while ActiveDocument.Selection.FindText(SearchString, vsFindOptions.vsFindOptionsFromStart + vsFindOptions.vsFindOptionsRegularExpression)
Dim TheFile
TheFile = ActiveDocument.Selection.Text
TheFile = Mid(TheFile, 8)
doc.Open(TheFile)
wend
ActiveDocument.Close()
end function
Tried and true "Flower Box" adder:
Function IsClassDef()
Dim ColNum
Dim LineNum
Dim sText
sText = ActiveDocument.Selection.ToString()
If sText = "" Then
'ActiveDocument.Selection.WordRight(dsExtend)
'sText = ActiveDocument.Selection
'sText = ucase(trim(sText))
End If
If (sText = "CLASS") Then
IsClassDef = True
Else
IsClassDef = False
End If
End Function
Sub AddCommentBlock()
'DESCRIPTION: Add Commecnt block to header, CPP files and Class Defs
AddCPPFileDesc()
End Sub
Sub AddCPPFileDesc()
'DESCRIPTION: Add File desc block to the top of a CPP file
Dim selection As EnvDTE.TextSelection
ActiveDocument.Selection.StartOfLine()
Dim editPoint As EnvDTE.EditPoint
selection = DTE.ActiveDocument.Selection()
editPoint = selection.TopPoint.CreateEditPoint()
Dim bOk, sExt, IsCpp, IsHdr, sHeader, IsCSharp
bOk = True
IsCpp = False
IsCSharp = False
If ActiveDocument.Selection.CurrentLine > 10 Then
If MsgBox("You are not at the top of the file. Are you sure you want to continue?", vbYesNo + vbDefaultButton2) = vbNo Then
bOk = False
End If
End If
If (bOk) Then
sExt = ucase(right(ActiveDocument.Name, 4))
IsCpp = sExt = ".CPP"
IsHdr = Right(sExt, 2) = ".H"
IsCSharp = sExt = ".CS"
If (IsCpp) Then
sHeader = left(ActiveDocument.Name, len(ActiveDocument.Name) - 3) + "h"
FileDescTopBlock(1)
editPoint.Insert("#include " + Chr(34) + "StdAfx.h" + Chr(34) + vbLf)
editPoint.Insert("#include " + Chr(34) + sHeader + Chr(34) + vbLf)
ElseIf (IsCSharp) Then
FileDescTopBlock(1)
Else
If IsHdr Then
'If IsCLassDef() Then
'AddClassDef()
'Else
AddHeaderFileDesc()
'End If
Else
FileDescTopBlock(1)
End If
End If
End If
End Sub
Sub AddHeaderFileDesc()
FileDescTopBlock(0)
Dim selection As EnvDTE.TextSelection
ActiveDocument.Selection.StartOfLine()
Dim editPoint As EnvDTE.EditPoint
selection = DTE.ActiveDocument.Selection()
editPoint = selection.TopPoint.CreateEditPoint()
editPoint.Insert("#pragma once" + vbLf)
End Sub
Sub FileDescTopBlock(ByVal HasRevHistory)
'DESCRIPTION: Add File desc block to the top of a CPP file
Dim selection As EnvDTE.TextSelection
ActiveDocument.Selection.StartOfLine()
ActiveDocument.Selection.EndOfLine()
Dim sComment
sComment = ActiveDocument.Selection.ToString()
If Left(sComment, 2) = "//" Then
ActiveDocument.Selection.Delete()
sComment = LTrim(Mid(sComment, 3))
Else
sComment = ""
End If
Dim sLineBreak
Dim sFileName
Dim sBlock
sLineBreak = "////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////"
sFileName = ActiveDocument.Name
ActiveDocument.Selection.StartOfDocument()
sBlock = sLineBreak & vbLf & _
"// File : " & sFileName & vbLf & _
"// Author : Larry Frieson" & vbLf & _
"// Desc : " & sComment & vbLf & _
"// Date : " & CStr(Now.Date()) & vbLf & _
"//" & vbLf & _
"// Copyright © 20" + Right(CStr(Now.Year.ToString()), 2) + " MLinks Technologies. All rights reserved" + vbLf
If (HasRevHistory > 0) Then
sBlock = sBlock & _
"//" & vbLf & _
"// Revision History: " & vbLf & _
"// " & CStr(Now) & " created." & vbLf & _
"// " & vbLf
End If
sBlock = sBlock + sLineBreak + vbLf
Dim editPoint As EnvDTE.EditPoint
selection = DTE.ActiveDocument.Selection()
editPoint = selection.TopPoint.CreateEditPoint()
editPoint.Insert(sBlock)
End Sub
Hope this helps, or at least gives you some ideas. Again, I didn't test/debug the "source file looper", I figure you can handle that.
Larry
LarryF
2009-01-06 02:02:36
+10
A:
Here you go, I provide an example for .cs and .vb but shouldn't be hard for you to adjust it to your other file type needs: Edited to recursively add header to sub-folders
Sub IterateFiles()
Dim solution As Solution = DTE.Solution
For Each prj As Project In solution.Projects
IterateProjectFiles(prj.ProjectItems)
Next
End Sub
Private Sub IterateProjectFiles(ByVal prjItms As ProjectItems)
For Each file As ProjectItem In prjItms
If file.SubProject IsNot Nothing Then
AddHeaderToItem(file)
IterateProjectFiles(file.ProjectItems)
ElseIf file.ProjectItems IsNot Nothing AndAlso file.ProjectItems.Count > 0 Then
AddHeaderToItem(file)
IterateProjectFiles(file.ProjectItems)
Else
AddHeaderToItem(file)
End If
Next
End Sub
Private Sub AddHeaderToItem(ByVal file As ProjectItem)
DTE.ExecuteCommand("View.SolutionExplorer")
If file.Name.EndsWith(".cs") OrElse file.Name.EndsWith(".vb") Then
file.Open()
file.Document.Activate()
AddHeader()
file.Document.Save()
file.Document.Close()
End If
End Sub
Private Sub AddHeader()
Dim cmtHeader As String = "{0} First Line"
Dim cmtCopyright As String = "{0} Copyright 2008"
Dim cmtFooter As String = "{0} Footer Line"
Dim cmt As String
Select Case DTE.ActiveDocument.Language
Case "CSharp"
cmt = "//"
Case "Basic"
cmt = "'"
End Select
DTE.UndoContext.Open("Header Comment")
Dim ts As TextSelection = CType(DTE.ActiveDocument.Selection, TextSelection)
ts.StartOfDocument()
ts.Text = String.Format(cmtHeader, cmt)
ts.NewLine()
ts.Text = String.Format(cmtCopyright, cmt)
ts.NewLine()
ts.Text = String.Format(cmtFooter, cmt)
ts.NewLine()
DTE.UndoContext.Close()
End Sub
Brian Schmitt
2009-01-06 02:11:15
Thanks, I'm gonna vote for this one instead of the one that has the link to the blog, because this shows how to enumerate the projects.
DSO
2009-01-06 02:27:33
How well does this work for files that have designers, like WinForms?
Scott A. Lawrence
2009-09-21 20:31:09
Should add it to any CS or VB file in the solution. Which would include the designer file - however as with any 'generated' file, the file could change and your comment may no longer be there.
Brian Schmitt
2009-09-22 14:38:39
Just what I was looking for! But the macro does not dive into sub folders and add headers to the files contained in them. Will post modified code if I find a solution.
SDX2000
2009-09-25 13:49:51