After some Googling I found this: Use a Visual Studio Macro to Insert Copyright Headers into Source Files. It looked promising:
// <copyright file="Sample.cs" company="My Company Name">
// Copyright (c) 2012 All Rights Reserved
// </copyright>
// <author>Leniel Macaferi</author>
// <date>08/30/2012 11:39:58 AM </date>
// <summary>Class representing a Sample entity</summary>
When I tried Tools -> Macros
menu option it wasn't there anymore in VS 2012. Here's the proof: Macros in Visual Studio 11 Developer Preview. They just dropped this functionality. :(
So, I'm just curious to know which option I could use to add the copyright info to all existing source code files in my solution using Visual Studio 2012. Is there any standard way of doing this, using a template file (something related to T4 templates
) or a PowerShell
script? I could write some code to iterate over the files with .cs
extension and add the copyright info but that is not what I'm after. I'd like to know about some tool to automate this process.
You could create a new snippet and just type cp + double tab to insert the notice where you want (needless to say you can change the keyword to whatever you want).
The only problem with it is, from what I'm aware, snippets do not support time functions, so getting the current time for your date line seems impossible with this technique. A not so good workaround for this is to make the time fields editable (similar to how the mbox snippet works) and just insert the time manually.
Here's an example on how a snippet looks. The bellow snippet will get the class name automatically and insert the copyright notice in the place where you type 'copyright' and double tab.
Method 1
<?xml version="1.0" encoding="utf-8" ?>
<CodeSnippets xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">
<CodeSnippet Format="1.0.0">
<Header>
<Title>Copyright</Title>
<Shortcut>Copyright</Shortcut>
<Description>Code snippet for Copyright notice</Description>
<Author>author name</Author>
<SnippetTypes>
<SnippetType>Expansion</SnippetType>
</SnippetTypes>
</Header>
<Snippet>
<Declarations>
<Literal Editable="false">
<ID>classname</ID>
<Function>ClassName()</Function>
</Literal>
</Declarations>
<Code Language="csharp">
<![CDATA[// <copyright file="$classname$" company="My Company Name">
// Copyright (c) 2012 All Rights Reserved
// <author>Leniel Macaferi</author>
// </copyright>
]]>
</Code>
</Snippet>
</CodeSnippet>
</CodeSnippets>
Method 2
Also, here's an example of a program you can make to do that for you.
List<string> files = new List<string>()
{
"c:\\Form1.cs",
"c:\\Form2.cs",
};
foreach (string file in files)
{
string tempFile = Path.GetFullPath(file) + ".tmp";
using (StreamReader reader = new StreamReader(file))
{
using (StreamWriter writer = new StreamWriter(tempFile))
{
writer.WriteLine(@"// <copyright file=" + Path.GetFileNameWithoutExtension(file) + @" company=My Company Name>
// Copyright (c) 2012 All Rights Reserved
// </copyright>
// <author>Leniel Macaferi</author>
// <date> " + DateTime.Now + @"</date>
// <summary>Class representing a Sample entity</summary>
");
string line = string.Empty;
while ((line = reader.ReadLine()) != null)
{
writer.WriteLine(line);
}
}
}
File.Delete(file);
File.Move(tempFile, file);
}
Some error catching will be required of course. But this should give you the general idea how to construct an UI around it an add the files you will want to process.
Method 3
It's also possible to change the template for your classes that can be usually be found under:
C:\Program Files (x86)\Microsoft Visual Studio <version>\Common7\IDE\ItemTemplates\CSharp\1033\
Sometimes editing ItemTemplatesCache is also necessary to display the results.
Here's an example template based on your question:
using System;
using System.Collections.Generic;
$if$ ($targetframeworkversion$ >= 3.5)using System.Linq;
$endif$using System.Text;
/* <copyright file=$safeitemrootname$ company="My Company Name">
Copyright (c) 2012 All Rights Reserved
</copyright>
<author>Leniel Macaferi</author>
<date>$time$</date>
<summary>Class representing a Sample entity</summary>*/
namespace $rootnamespace$
{
class $safeitemrootname$
{
}
}
I'm going to add here a PowerShell script I found in this post: Powershell – Copyright header generator script. It captures what I had in mind before posting the question...
param($target = "C:\MyProject", $companyname = "My Company")
$header = "//-----------------------------------------------------------------------
// <copyright file=""{0}"" company=""{1}"">
// Copyright (c) {1}. All rights reserved.
// </copyright>
//-----------------------------------------------------------------------`r`n"
function Write-Header ($file)
{
$content = Get-Content $file
$filename = Split-Path -Leaf $file
$fileheader = $header -f $filename,$companyname
Set-Content $file $fileheader
Add-Content $file $content
}
Get-ChildItem $target -Recurse | ? { $_.Extension -like ".cs" } | % `
{
Write-Header $_.PSPath.Split(":", 3)[2]
}
I wrote about it with minor modifications to adapt it to my needs:
Inserting copyright notice/banner/header in all source code files with PowerShell
In case this might still be interesting, there is the License header plugin that can add a completey customizable header to any file on creation. Currently, this does work with VS2013, but not (yet?) with VS 2015.
After losing work to some obscure PowerShell script (not the one added as an answer), I decided to create copyright.py. Example usage:
C:\>python copyright.py "C:\users\me\documents\path\to\vsproject"
It recursively finds all *.cs files in the specified directory and prefixes them with the copyright text. It does not matter if other text already exists at the start of the file; it will be removed.
Note: As a precaution, you should always backup your code before executing this script
A simpler version of the code by @leniel-macaferi (no filename and company, just header):
param($target = "C:\MyProject")
$header = "//-----------------------------------------------------------------------------
// Copyright (c) The Corporation. All rights reserved.
//-----------------------------------------------------------------------------
"
function Write-Header ($file)
{
$content = Get-Content $file
$filename = Split-Path -Leaf $file
$fileheader = $header
Set-Content $file $fileheader
Add-Content $file $content
}
Get-ChildItem $target -Recurse | ? { $_.Extension -like ".cs" } | % `
{
Write-Header $_.PSPath.Split(":", 3)[2]
}
To run, save the code in a new file (e.g. AddHeader.ps1) in the directory you want to recursively iterate through and execute .\AddHeader.ps1 .
from PowerShell window.