Updated PowerShell script to insert copyright notice/banner/header in all source code files

In a recent post I described how one could insert a copyright banner in all source code files located on a given path. You can read all the details about it here: Inserting copyright notice/banner/header in all source code files with PowerShell script

During the past month or so I updated that PowerShell script to give it even more power. In the Notes section of that post I mentioned this point:


  • Beware that if you run the script twice it'll add the copyright notice twice in each file

With this updated version (see the highlighted parts) I’ve overcome such limitation.

I’m now also using the built-in Powershell Filter keyword to filter the files, that is, processing only .cs files (C# code files) excluding some other files that have the .cs extension but that have a given naming pattern. I exclude those files because it doesn’t make sense to add copyright to them and because in some cases it would break the build.

Here’s the updated PowerShell script with comments to help you understand what’s going on in each line:

param($target = "C:\MyProject\trunk", $companyname = "Leniel’s Software House")

#[System.Globalization.CultureInfo] $ci = [System.Globalization.CultureInfo]::GetCultureInfo("pt-BR")

[System.Globalization.CultureInfo] $ci = [System.Globalization.CultureInfo]::GetCurrentCulture

# Full date pattern with a given CultureInfo
# Look here for available String date patterns: http://www.csharp-examples.net/string-format-datetime/
$date = (Get-Date).ToString("F", $ci);

# Header template
$header = "//-----------------------------------------------------------------------

// <copyright file=""{0}"" company=""{1}"">

// Copyright (c) {1}. All rights reserved.

// <author>Leniel Macaferi</author>

// <date>{2}</date>

// </copyright>

//-----------------------------------------------------------------------`r`n"

function Write-Header ($file)
{
    # Get the file content as as Array object that contains the file lines
    $content = Get-Content $file
    
    # Getting the content as a String
    $contentAsString =  $content | Out-String
    
    <# If content starts with // then the file has a copyright notice already
       Let's Skip the first 14 lines of the copyright notice template... #>
    if($contentAsString.StartsWith("//"))
    {
       $content = $content | Select-Object -skip 14
    }

    # Splitting the file path and getting the leaf/last part, that is, the file name
    $filename = Split-Path -Leaf $file

    # $fileheader is assigned the value of $header with dynamic values passed as parameters after -f
    $fileheader = $header -f $filename, $companyname, $date

    # Writing the header to the file
    Set-Content $file $fileheader -encoding UTF8

    # Append the content to the file
    Add-Content $file $content
}

#Filter files getting only .cs ones and exclude specific file extensions
Get-ChildItem $target -Filter *.cs -Exclude *.Designer.cs,T4MVC.cs,*.generated.cs,*.ModelUnbinder.cs -Recurse | % `
{
    <# For each file on the $target directory that matches the filter,
       let's call the Write-Header function defined above passing the file as parameter #>
    Write-Header $_.PSPath.Split(":", 3)[2]
}
Hope you make even better use of such a pearl that comes in handy from time to time.

Mp3tag and its useful actions like Replace with regular expression and Guess values

Every once in a while I’m in a situation where I need to refresh my mind about how to work with regular expressions and guess values in Mp3tag to batch process lots of MP3 in a single shot… I’ll try to keep this post as a reference for the artifices I use with Mp3tag so that I can get back here and see what and how I did to format my MP3 tags the way they should be.

Mp3tag - The Universal Tag EditorMp3tag is IMHO the best MP3 tag editor out there. I’m so satisfied with it that I stopped trying to find a better tool. Nonetheless, I’m open to recommendations…

Mp3tag is a powerful and yet easy-to-use tool to edit metadata of common audio formats where it supports ID3v1, ID3v2.3, ID3v2.4, iTunes MP4, WMA, Vorbis Comments and APE Tags.

It can rename files based on the tag information, replace characters or words in tags and filenames, import/export tag information, create playlists and more.

I’ve been writing about MP3 in this blog. If you’re interested, you can check past posts here

As I commented above, to refresh my mind I tend to look for this post I wrote some time ago: More MP3 guessing pattern with Mp3tag in Mac OS but I decided to compile future endeavors in this area in a single post. I hope you enjoy.

This time I’m using Mp3tag in the Windows 8 side inside a Parallels Desktop virtual machine.

OK. After some formalities, let’s complete these five basic steps needed in every use case I’ll present in this post:

1 - Click the change directory button and navigate to the folder where you store the MP3s you want to edit.

Mp3tag Change Directory button

2 - Select the files you want to edit. I just press Ctrl + A to select all the files. You can also hold Ctrl to select file by file.

3 - Click the Actions (Quick) button.

Mp3tag Actions (Quick) button

4 - Follow the use cases…

Removing year between parenthesis from file name

Guessing values for Artist and Title from file name

5 - DO NOT FORGET to click the Save button after executing the actions of each use case so that the changes get applied to the files; otherwise you’ll lose the edits. Confused smile

Mp3tag Save button

Use cases

Removing year between parenthesis from file name

Mp3tag Filename with Year between parenthesis

After clicking the Actions button, select Replace with regular expression, select the _FILENAME field and enter the regular expression \( 2o12 \). Press OK and you’re done:

Mp3tag File name with Year between parenthesis regex

Guessing values for Artist and Title from File name

Mp3tag Guess Values for Artist and Title from File name

As you see the MP3 files don’t have Artist and Title information. This is bad. If you use services like Last.fm to keep track of the music you’ve been listening to, you won’t be able to scrobble given the missing metadata. Of course you can fill the info by hand (Oh Lord! How boring and time consuming this task is). There’s Mp3tag to the rescue.

Taking the previous use case as a necessary step to format the file name accordingly…

After clicking the Actions button, select Guess values, in Source format enter %_filename%, in Guessing pattern enter \%artist% - %title%. Press OK and you’re done:

Mp3tag Guess Values for Artist and Title from File name regex

References

MP3 Tag - The Universal Tag Editor Help pages

JavaScript regex + jQuery to allow only English chars/letters in input textbox

Yesterday I answered this question at StackOverflow. The questioner wanted this:

How to allow only English, numeric and special chars in textbox using jQuery or JavaScript?

My answer was this:

$('#mytextbox').bind('keyup blur', function () {
    $(this).val($(this).val().replace(/[^A-Za-z]/g, ''))
});

It has a flaw because if you test it, you’ll see that every time a disallowed character is typed, the keyboard caret/text cursor goes to the end of the textbox. This is something that shouldn’t happen. Aristos mentioned something that I hadn’t tested: “the problem with your answer is that if you try to type something in the middle of the text, the cursor moves to the end.” He is absolutely right. You can test it below. Click the Result tab and type a digit like 7 or some other disallowed char in the middle of the textbox text to spot the problem:

OK – of course there must be a solution to this annoying problem and I couldn't miss the opportunity to play with it to find something that just works as expected. This answer by Ender helped me get there. The following code is what I came up with. I commented the code so it should be easy to understand what's going on:

$("#mytextbox").on("keypress", function (event) {

    // Disallow anything not matching the regex pattern (A to Z uppercase, a to z lowercase and white space)
    // For more on JavaScript Regular Expressions, look here: https://developer.mozilla.org/en-US/docs/JavaScript/Guide/Regular_Expressions
    var englishAlphabetAndWhiteSpace = /[A-Za-z ]/g;

    // Retrieving the key from the char code passed in event.which
    // For more info on even.which, look here: http://stackoverflow.com/q/3050984/114029
    var key = String.fromCharCode(event.which);

    //alert(event.keyCode);

    // For the keyCodes, look here: http://stackoverflow.com/a/3781360/114029
    // keyCode == 8  is backspace
    // keyCode == 37 is left arrow
    // keyCode == 39 is right arrow
    // englishAlphabetAndWhiteSpace.test(key) does the matching, that is, test the key just typed against the regex pattern
    if (event.keyCode == 8 || event.keyCode == 37 || event.keyCode == 39 || englishAlphabetAndWhiteSpace.test(key)) {
        return true;
    }

    // If we got this far, just return false because a disallowed key was typed.
    return false;
});

$('#mytextbox').on("paste", function (e) {
    e.preventDefault();
});

Try it below:

Now you can type in the middle of the text and the text cursor should maintain its position.

The above version allows accented chars like á, é, â, ê, etc…

Note also that there’s a new event handler function (paste) attached to the input textbox. This removes the possibility of user pasting text in the textbox.

If you want to allow numbers/digits or any other special characters, it’s just a matter of updating the regular expression pattern. For example: if you want to allow digits from 0 to 9, just use this regex pattern:

var englishAlphabetAndDigits = /[A-Za-z0-9 ]/g;

Full code:

$("#mytextbox").on("keypress", function (event) {

    // Disallow anything not matching the regex pattern (A to Z uppercase, a to z lowercase, digits 0 to 9 and white space)
    // For more on JavaScript Regular Expressions, look here: https://developer.mozilla.org/en-US/docs/JavaScript/Guide/Regular_Expressions
    var englishAlphabetDigitsAndWhiteSpace = /[A-Za-z0-9 ]/g;

    // Retrieving the key from the char code passed in event.which
    // For more info on even.which, look here: http://stackoverflow.com/q/3050984/114029
    var key = String.fromCharCode(event.which);

    //alert(event.keyCode);

    // For the keyCodes, look here: http://stackoverflow.com/a/3781360/114029
    // keyCode == 8  is backspace
    // keyCode == 37 is left arrow
    // keyCode == 39 is right arrow
    // englishAlphabetDigitsAndWhiteSpace.test(key) does the matching, that is, test the key just typed against the regex pattern
    if (event.keyCode == 8 || event.keyCode == 37 || event.keyCode == 39 || englishAlphabetDigitsAndWhiteSpace.test(key)) {
        return true;
    }

    // If we got this far, just return false because a disallowed key was typed.
    return false;
});

$('#mytextbox').on("paste", function (e) {
    e.preventDefault();
});

Here’s an updated jsFiddle that allows digits:

It’s really impressive what some small amount of JavaScript and jQuery code allows you to do on the client side. Actually if you care there are more comments than codez… Surprised smile

There’s no doubt JavaScript and JQuery will reign in the years to come.

About the code
As everything in software the above piece of code needs more testing. If you find a bug or some functionality that is missing, just leave a comment.

References
JavaScript Regular Expressions Guide by Mozzila.org

Delete Blogger Navbar section/widget from your blog template code

In the past I used to just hide Blogger’s navbar widget with some CSS code but it was still there being loaded in the HTML code. This approach is inefficient because I really don’t want the navbar. So why should it still be there in the code taking some precious time to load and impacting the user experience?

Blogger navbarFigure 1 - Blogger navbar

In my case when I looked at the Layout section of my blog in Blogger dashboard I saw that the navbar section was locked (see the locked=’true’ in Figure 2) which means I could not delete it in the Layout screen. So there’s only one option to really get rid of it and it is through the widget code.

If you look carefully you’ll note that the navbar’s code loads some JavaScript files as the Google Plus One plusone.js file. This is impacting my page load speed because I’m already loading the plusone script somewhere else since I have a customized template. This leads to duplicate requests for the same JavaScript file. This is really really bad. There’s no need for it.

So I was after a way of removing the navbar forever; not just hiding it with CSS. I then found a way of doing it but it didn’t work for me. Blogger redesigned its interface and maybe this is the problem.

Then I just thought: what if I try to select the navbar section code and delete it and hit save on the HTML template – who knows… this can work out. What’s the result: it does work out.

How to do it? Follow these 10 simple steps…

1 - First save a backup copy of your blog template for the case where something goes wrong;

2 - Go to Blogger dashboard and select Template in the menu on the left;

3 - Hit the Backup / Restore button at the screen top right and save a backup copy of your layout;

4 - In the Template screen, click Edit HTML button;

5 - Click the checkbox Expand Widget Templates;

6 - Hit Ctrl + F and find the string ‘navbar’;

7 - Select the section code like the one shown in the following screenshot:

Selecting the navbar section/widget code while editing the blog’s template HTML codeFigure 2 - Selecting the navbar section/widget code while editing the blog’s template HTML code

8 - Hit delete on the keyboard;

9 - Click the Save template button in orange. You should get this message:

Warning message informing that deleting the navbar widget cannot be undoneFigure 3 - Warning message informing that deleting the navbar widget cannot be undone

10 - Click Delete widgets button and you’re done. Smile

Now your page will load a bit faster and this is pretty nice for the user visiting your blog.

Inserting copyright notice/banner/header in all source code files with PowerShell script

I have a better version of this PowerShell script if you’re interested.
I suggest you read this post first (there’s a bonus point) then go take a look at the new one here:
Updated PowerShell script to insert copyright notice/banner/header in all source code files

Today my client asked for the source code of a project we worked together. He wants to submit it to patent review and he wanted to include a copyright notice in each C# code file (.cs).

I googled about a way of accomplishing this and found this post:

Use a Visual Studio Macro to Insert Copyright Headers into Source Files

It looked promising but as I’m working with Visual Studio 2012 I just hit a road block because it dropped the support for Macros. So I had to find some other way… in the meantime I asked a question at StackOverflow to see if someone had any good advice regarding this. Right now there’s one nice answer but it requires manual work. I’m really interested in an automated process (do the work in a batch fashion) because there are lots of .cs files in the Visual Studio solution comprised of 7 projects.

Some more Googling with the right words (read PowerShell) and I was able to find something that could do the work. Kishor Aher wrote about it Powershell – Copyright header generator script. Oh God, the internet is really amazing thingy! Remember to just search for the right words…

Now it was just a matter of adapting the PowerShell script to my needs. Here is it:

param($target = "C:\MyProject", $companyname = "My Company", $date = (Get-Date))

$header = "//-----------------------------------------------------------------------

// <copyright file=""{0}"" company=""{1}"">

// Copyright (c) {1}. All rights reserved.

// <author>Leniel Macaferi</author>

// <date>{2}</date>

// </copyright>

//-----------------------------------------------------------------------`r`n"

function Write-Header ($file)
{
    $content = Get-Content $file

    $filename = Split-Path -Leaf $file

    $fileheader = $header -f $filename,$companyname,$date

    Set-Content $file $fileheader

    Add-Content $file $content
}

Get-ChildItem $target -Recurse | ? { $_.Extension -like ".cs" } | % `
{
    Write-Header $_.PSPath.Split(":", 3)[2]
}

As you see above, the script will place the copyright notice in every .cs file that lies within the folder C:\MyProject. So let’s say you have a Visual Studio solution with various projects – the script will traverse all files placing the notice in every .cs file it finds along the way…

I named the script Copyright.ps1.

To make this work I just opened PowerShell command line, navigated to the folder where I placed the script file and typed .\Copyright.ps1 to run the script:

Executing Copyright PowerShell script using PowerShell command line toolFigure 1 - Executing Copyright PowerShell script using PowerShell command line tool

You’re done!

Enjoy.

Notes

  • Close Visual Studio solution before running the PowerShell script. Otherwise you may get some error message telling you that some file is in use.
  • Be sure to have your source code files commited in a source control repository before running the scripts so that if anything goes wrong you can just revert to the previous state.
  • Beware that if you run the script twice it'll add the copyright notice twice in each file.

A big thank you to Kishor for providing us the PowerShell script. I’m not that experienced with PowerShell but adapting existing scripts is something easy to do IMHO.

Bonus
To get support for PowerShell scripting in Visual Studio with syntax highlighting and IntelliSense, there’s an awesome and free product out there. It’s called PowerGUI. In order to use it, download PowerGUI here and then install its accompanying Visual Studio extension available here. As I’m using Visual Studio 2012 I had to install the alpha release available here.

See for yourself the awesomeness:

PowerGUI editing PowerShell script with full IntelliSense support and Code Highlighting
Figure 2 - PowerGUI editing PowerShell script with full IntelliSense support and Code Highlighting

string.Format with dynamic length left aligned text in C#

This post is about dynamic text alignment with C#.

Scenario: I wanted to implement a dropdownlist with list items left aligned based on a string format. This is the initial appearance of the dropdown with no text alignment applied:

DropDownList with Text not alignedFigure 1 - DropDownList with Text not aligned

See that because Hospital names that come before => have different lengths, it doesn’t look good. Start and End dates are not aligned due to this.

So I thought about adding some caring to this and remembered that C# supports what I want to do. It’s called Composite Formatting. This when used with the Alignment Component allows some nice implementations.

The optional alignment component is a signed integer indicating the preferred formatted field width. If the value of alignment is less than the length of the formatted string, alignment is ignored and the length of the formatted string is used as the field width. The formatted data in the field is right-aligned if alignment is positive and left-aligned if alignment is negative. If padding is necessary, white space is used. The comma is required if alignment is specified.

Look at the following action method that lies within an ASP.NET MVC app. It’s responsible for adding list items to the dropdown show above…

[GET("Reports")]
public virtual ActionResult Index()
{
    ReportViewModel model = new ReportViewModel();

    // Getting the length of the lengthiest FictitiousName using Max query operator
    var maxLength = Database.Assessments.Max(a => a.Hospital.FictitiousName.Length);

    // Here’s the dynamic part: maxLength is used inside a format string to right align all strings, hence the minus sign. Doing this all strings will be equally left aligned (by maxLength) no matter their size.
    // {0}, {1} and {2} are positional parameters.
    string format = "{0, -" + maxLength + "} => {1} - {2}";

    List<SelectListItem> items = new List<SelectListItem>();

    foreach(Assessment a in Database.Assessments)
    {
        SelectListItem item = new SelectListItem();

        // Here's where the format string is used...
        item.Text = string.Format(format,
            a.Hospital.FictitiousName, a.StartDate.ToShortDateString(), a.EndDate.ToShortDateString());

        // This is necessary so that white spaces are respected when rendering the HTML code.
        item.Text = item.Text.Replace(" ", HttpUtility.HtmlDecode("&nbsp;"));

        item.Value = a.AssessmentId.ToString();

        items.Add(item);
    }

    model.Assessments = new SelectList(items.OrderBy(i => i.Text), "Value", "Text");

    return View(model);
}

With this code, now the result (really better to spot the dates) is this:

DropDownList with Text aligned using a format string dynamically builtFigure 2 - DropDownList with Text aligned using a format string dynamically built

maxLength in this case = 20. This is the length of “Unimed Volta Redonda” (the lengthiest string in the list) in this specific case. The format string uses this value to left align this and all other strings with smaller lengths “equally” adding white spaces to compensate the smaller strings.

One really import thing to take into consideration when doing what this post proposes is to use a monospaced font or fixed-width font, because its letters and characters each occupy the same amount of horizontal space. If you don’t use this kind of font, you won’t get the desired result.

This is the Razor view code:

<div id="reports">

@Html.LabelFor(m => m.Assessments)&nbsp; @Html.DropDownListFor(m => m.AssessmentId, Model.Assessments, string.Format(Localization.SelectValue2, Localization.Assessment), new { data_bind="value: selectedAssessment" } )

</
div>

So in order to make it work I added this CSS code:

#reports select
{
    font-family: 'Courier New'; /* well known monospaced font */
    width: auto;
}

Happy C# dynamic text aligning to everyone!

Debugging Microsoft Web Deploy Visual Studio publishing errors

This post is intended for starters with MS Web Deploy as is my case… Shifty

Microsoft Web Deploy is so awesome that I think it’s one of the best features one has at their disposal when developing with the .NET Framework and for the Web with ASP.NET MVC for example. It’s so powerful that it can even publish a database.

Once upon a time (let’s say before 2010) there was no Web Deploy and you had to FTP to the server to deploy the application. This was a tiresome task and led to many errors because one had to be extremely careful of what files needed to be updated, added, removed, etc while installing the application on the server. Backup methods should be in place in case something went wrong. I used to use compressed files (.zip or .rar) to send the app’s files to the server. It was still a big upload in some cases. I had to wait patiently. Once there I had to uncompress the file. Everything needed to be moved into place to make things easier. I even created a step by step readme file to help other peers do the deploy on the server. This readme detailed the workflow that should be followed in order to get things working.

Thanks God today there’s Web Deploy and it changed things drastically: only new or updated files are uploaded to the server. No more long waiting periods to start using the application. As a bonus you also have the option of removing additional files on the server (files/folders that aren’t used anymore). All this happens automatically (could we say automagically) with the click of a button inside Visual Studio 2010 or 2012. You can also run a .cmd file in the command line. This .cmd file is created as part of the Web Deploy Package publish method that you can choose once inside Visual Studio. There’s so many awesome features (read Preview menu option in Figure 4 bellow) that they would not fit in this post… To get a full understanding about Web Deploy look at this post: Visual Studio 2012 RC Deployment Docs.

Well, 2 weeks ago I tried to solve a problem related to Web Deploy. You can read the full history here:

Visual Studio 2012 Web Deploy to Windows Server 2008 R2 with IIS 7 and /msdeploy.axd 404 error

The above problem wasn’t solved but I can tell you that I learned a LOT about IIS administration during that weekend. As a result it was worth the effort. I think that a clean install of Windows Server 2008 is necessary in that case…

Today I was facing a different error (again working against Windows Server 2008 R2) and I followed a simple path to solve it. So here are the basic steps you need to follow to detect the problem’s origin:

Visual Studio 2012 Publish project with Web Deploy and Validate Connection errorFigure 1 - Visual Studio 2012 Publish project with Web Deploy and Validate Connection error

As you see when I clicked the Validate Connection button I got a message: ERROR COULD NOT CONNECT TO REMOTESVC.

If you click the error message, there’s some more info about the error but it doesn’t really tell you what’s causing the problem.  It’s kind of a generic message you get: go check the Web Management Service on your server… I think I don’t need to tell you that it’s started already! Steaming mad

Figure 2 - Visual Studio 2012 Publish project with detailed ERROR informationFigure 2 - Visual Studio 2012 Publish project with “detailed” ERROR information

To really get to the problem, you’ll need to access the server you’re trying to deploy to. Once there go to this folder:

C:\inetpub\logs\wmsvc\W3SVC1

This is the standard path where Web Management Service logs what’s going on…

When I opened the latest .log file I saw this:

#Software: Microsoft Internet Information Services 7.5
#Version: 1.0
#Date: 2012-07-26 15:50:30
#Fields: date time s-ip cs-method cs-uri-stem cs-uri-query s-port cs-username c-ip cs(User-Agent) sc-status sc-substatus sc-win32-status time-taken
2012-07-26 12:50:30 192.168.100.77 HEAD /msdeploy.axd site=Default%20Web%20Siste 8172 - 189.24.83.277 - 401 2 5 1918
2012-07-26 12:50:33 192.168.100.77 HEAD /msdeploy.axd site=Default%20Web%20Siste 8172 develop
189.24.83.277 - 550 0 0 2761

As you see highlighted in orange is my developer machine IP address. This let’s me know that my connection to server is working as expected. Port 8172 is not blocked by the firewall, etc.
Highlighted in yellow is a sc-status = 550. This is the key part while debugging errors related to web deploy on the server. Now it’s far easier to know what’s the problem. It’s only a matter of Googling about the 550 status code. The first post that mentions this status code was this one:

Status code 550 when using Msdeploy

The guy lost 1 day to find what was going on and it took me only 1 minute to figure out the error I had with his help. He talks about the site’s name displayed in IIS manager. So I went check mine and to my surprise I had a small mistake in the Site/application name field shown in Figure 1. I typed Default Web Siste instead of only Default Web Site. What a silly mistake!

This is the kind of error that can bother you more than it should… believe it or not. You can go the wrong way while trying to get things working as expected.

After correcting this mistyped named I clicked the Validate Connection button again and to my delight and surprise I got this beautiful green check mark:

Visual Studio 2012 Publish project with Web Deploy and successful connection validationFigure 3 - Visual Studio 2012 Publish project with Web Deploy and successful connection validation

Now if you desire select the Preview menu option to glance at what’s going to the server…

Visual Studio 2012 Publish project with Web Deploy and Previewing the changes
Figure 4 - Visual Studio 2012 Publish project with Web Deploy and Previewing the changes

You can select just the files you want to deploy. This is super useful let’s say when you discover a bug in production and want to change something in whatever file to correct that bug. You already have more changes to pull to the server but you just want to correct that bug. With the Preview tab you can do this: select just the file(s) you changed to correct the bug and deselect all the others. Isn’t this awesome? Of course it is!

If it’s OK, just hit the Publish button and you’re good to go.

I hope this simple post helps you find the root cause of what’s causing errors while you’re trying to deploy your application using MS Deploy.

References
Configuring a Web Server for Web Deploy Publishing (Remote Agent)

Installing and Configuring Web Deploy

Web Deploy error codes