Inserting copyright notice/banner in all source code files in Visual Studio 2012
Asked Answered
L

7

49

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.

Laurilaurianne answered 30/8, 2012 at 14:38 Comment(8)
Could you use a pre/post build step that runs a powershell script that checks if each CS file has a given header, and prepend it if it doesn't?Willi
@PhonicUK: this would be a good option. I'm just not that versed with PowerShell. :)Laurilaurianne
Or write a small C# app that does this instead and run that?Willi
@PhonicUK: as I said... I could do this, but I'm after some existing tool/extension/whatever to automate the whole process.Laurilaurianne
If you are confortable to spending some money there it the PRO version of GhostDoc. An addin that document your code (alas the free version doesn't support your scenario)Lite
Indeed, but with macros having being removed then it looks like you're SOL unless an extension exists that can do this or you roll your own.Willi
This is (unfortunately) only for VB.NET but you can change the default XML documentation template for classes etc as described here. Aside from that, wouldn't it be better to leave metadata such as creation date, author etc over to your source control system?Danieu
@Laoujin: unfortunately this is VB only. The author info must be included in the source file. The client is asking for this to patent the code.Laurilaurianne
M
37

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$
    {
    }
}
Muttonchops answered 30/8, 2012 at 15:23 Comment(10)
Really interesting approach! The only drawback I see is that this is a manual process. I must open each .csfile I have to add the copyright notice. Any way of doing this in a batch?Laurilaurianne
Sadly I don't know if there is a way of modifying the .cs files without opening them (although it looks extremely easy to make a program that does that for you). I will be interested if you manage to find one since I was looking for a faster solution myself. As for making one yourself, the approach looks easy. Add the files you want in an array, iterate through each of them and then insert the comment lines where you want them.Muttonchops
Updated the post with some code in case you decide to take the "making your own solution" route and also some guidelines for editing your templates.Muttonchops
+1 for the effort. I'll accept your answer since you showed a lot of attention and different ways of doing the task. Take a look at my answer. I think that PowerShell script captures well what I had in mind. The 3rd method you show in your answer is pretty good when you're starting a new project.Laurilaurianne
Powershell does indeed look interesting. May I ask why you prefer Powershell over making your own program ? Although I assume the ability to modify the code without opening an IDE is one of them.Muttonchops
Yes... PowerShell script is really versatile and can be hooked in a lot of places with little or no effort at all.Laurilaurianne
Very nice thanks. Re #1 also see Walkthrough: Creating a Code SnippetReinforcement
$classname$ isn't working for me for some reason in visual studio 2017.Escamilla
The latest documentation I could find (learn.microsoft.com/en-gb/visualstudio/ide/…) implies that this still works. I will test it as well when I get the chance.Muttonchops
Just finished testing it, it worked just fine using VS 2017 15.5.6. Ensure your declarations are correct and that you are inside a Class when using the shortcut.Muttonchops
L
23

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

Laurilaurianne answered 30/8, 2012 at 19:56 Comment(2)
While I appreciate coolmine's effort, yours is the answer any googler would be looking for. Perhaps go ahead and accept your own answer. :)Dunk
It would be nice if the function was a bit 'smarter' and replaced any existing headers so you could run it multiple times without spamming headersShuntwound
L
10

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.

Lidda answered 17/8, 2015 at 16:44 Comment(4)
Is it also possible to have the filename generated in the license header?Indignant
Yes, via %FileName%. Have a look at the wiki at their GitHub Page (github.com/rubicon-oss/LicenseHeaderManager), the bullet point "Expendable Properties" lists all possible replacements.Lidda
Supports VS 2017 as well.Froh
also works for VS2015Radiolucent
L
5

As per the release notes the release notes (scroll down a bit), Visual Studio 16.6 allows to define a file_header_template rule in .editorconfig that can be used to create file banners.

Lidda answered 26/5, 2020 at 14:49 Comment(3)
Unfortunately the release notes don't seem to show how to use that option, they just mention it exists. Can you elaborate at all? This sounds like a promising solution but unfortunately I can't find anything about it in my searchesAzygous
@Azygous I didn't try it myself - but I updated the link above, maybe that can help you further.Lidda
it didn't work for me :(Egyptology
B
4

Add a .editorconfig file to your Visual Studio project with following line:

file_header_template = // <copyright file="{fileName}.cs" company="xyz Corporation">\n// Copyright (c) Xyz Corporation. All rights reserved.\n// </copyright>

Next, place your cursor on the first line of any C# or Visual Basic file and type (Ctrl+.) to trigger the Quick Actions and Refactorings menu. Select Add file banner. If you would like to apply the file header to all files of an existing project or solution, select Project or Solution under the Fix all occurrences in: option.

This approach will work for new files and even existing files. This is inbuilt in visual studio code so you don't need custom scripts.

Details here: https://learn.microsoft.com/en-us/visualstudio/releases/2019/release-notes-v16.6#net-productivity:~:text=Add%20file%20headers%20to%20existing%20files

Bookcraft answered 28/4, 2021 at 15:29 Comment(2)
This is perfect for anyone using a newer version of Visual Studio. You can even add the .editorconfig file to the solution. This way when you press CTRL+. on a file -> Add Header, you can apply it to either Document, Project, or Solution levels.Yearbook
this didn't work for VS2022, no matter where I put the .editorconfigEgyptology
G
2

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

Ghiselin answered 30/10, 2014 at 16:37 Comment(0)
P
1

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.

Padron answered 21/7, 2015 at 23:35 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.