Wednesday, March 23, 2016

Installing Software on Windows the Easy Way (Using Chocolatey)

I've been using Chocolatey for a while now, and today I want to share the coolness, for those of you that haven't heard of it or used it. It’s much like apt-get for Windows (automatic way to install software from the web).

You install it by running this on the command line:

@powershell -NoProfile -ExecutionPolicy Bypass
-Command "iex ((new-object net.webclient).DownloadString(''))"

After that, let’s say you want to install Chrome, it’s simple as (running from CMD)
choco install chrome

or EverNote:
choco install evernote

or Node:
choco install nodejs.install

You just have to remember to run CMD as administrator. Bypass the license prompt by using the "-y" command argument. You can install any of the 3779 packages it supports. They are listed at

Monday, March 14, 2016

Using NUnit 3.2 with ReSharper Ultimate 10

I just upgraded my ReSharper to 10 in the hope that it will fully support NUnit 3.2 (the most current version as of the time of me writing this). However that didn’t turn out to be the case. I still had to Google around to find why ReSharper won’t run my tests while using NUnit 3.2. The solution turned out to be simple – install the ReSharper NUnit runner for NUnit 3 through the package console and restart Visual Studio!

Install-Package NUnit.ReSharperRunner3

Sunday, March 13, 2016

Poor Man’s Batch Encoding with HandBrake

I wanted to have a way to batch encode a directory (or even multiple directories) full of files without having to use the HandBrake interface to queue each directory. Ideally, I will do this in .NET in the long run but for now, here is a simple way to walk through all the directories and encode all files with the same HandBrake settings.

How it Works

  1. Deletes any existing files with the names “_encode_info.log” and “_encode_progress.log”
  2. Gets all the files in the directory and sub directories where it runs, ignoring itself
  3. For each file it finds:
    1. it gets the name of the directory the file is in, creates a directory with the same name under the “destinationPathRoot.”
    2. Sets the name of the output file to be under the newly created directory under “destinationPathRoot”
    3. If the file already exists, it sets it’s name to have the current date and time (to avoid overwriting)
    4. Calls the EncodeVideo function with the source file path and destination file path
    5. If the destination file path exists after the encoding, it deletes the source file path


  • handBrakeExecutable – Set the path to the HandBrakeCLI executable
  • destinationPathRoot – The root of the path where to put the encoded files

How to Use It

Copy the contents below and paste it in a .bat file. I name mine according to the HandBrake arguments I’m using. For example “_encode-Q25-1Audio,bat” (meaning using variable quality of 25 with 1 audio stream). Copy the .bat file in the root of the directory where your videos reside. Run it.


@echo off
setlocal enabledelayedexpansion enableextensions

rem Set the path to the Handbrake executable
set handBrakeExecutable=Path\To\HandBrakeCLI.exe

rem Set the root path where files will be encoded to
set destinationPathRoot=Path\To\Done\Videos

if exist "%CD%\_encode_info.log" del "%CD%\_encode_info.log"
if exist "%CD%\_encode_progress.log" del "%CD%\_encode_progress.log"

rem Get all the files in the directory and sub-directories
for /f "tokens=* delims=|" %%G in ('dir /s /a-d /b *.*') do if not %%~xG==.bat (
    rem Set the source file path
    set sourceFilePath=%%G

    rem Get the current directory and remove the trialing slash
    set currentDirectory=%%~dpG
    set currentDirectoryNoTrailingSlash=!currentDirectory:~0,-1!

    rem Get only the name of the current directory
    for %%f in (!currentDirectoryNoTrailingSlash!) do set currentDirectoryName=%%~nxf

    rem Create the path to the destantion path based on the current directory name
    set destinationPath=!destinationPathRoot!\!currentDirectoryName!

    rem if the destination doesn't exist, create it
    if not exist !destinationPath! (
         mkdir !destinationPath!

    rem Process the file
    echo File: %%G

    rem Set the destination file based on the destination path and the current file name
    set destinationFilePath=!destinationPath!\%%~nG.mp4

    rem If the filename already exists, append the current date and time to it
    if exist destinationFilePath (
        rem Get the current date and time in MMDDYY_HH_MM_SS format
        for /f "tokens=1-8 delims=:./ " %%G in ("%date%_%time%") do (
            set currentDateTime=%%G%%H%%I_%%J_%%K

        set destinationFilePath=!destinationPath!\%%~nG-!currentDateTime!.mp4

    rem Call Handbrake to encode the file
    call :EncodeFile "!sourceFilePath!", "!destinationFilePath!"

    rem Delete the source file if the destination exists
    if exist !destinationFilePath! (
        del "!sourceFilePath!"


rem echo Source: %~1
rem echo Destination: %~2

rem Call HandBrakeCLI to encode the file
"!handBrakeExecutable!" ^
-I "%~1" ^
-o "%~2" ^
-f mp4 ^
-O ^
--decomb="fast" ^
--crop 0:0:0:0 ^
--strict-anamorphic ^
--modulus 2 ^
-e x264 ^
-q 25.0 ^
--cfr ^
-a 1 ^
--encoder-level="4.0" ^
--encoder-profile=high ^
1> _encode_progress.log ^
2> _encode_info.log


Wednesday, April 29, 2015

OctopusDeploy CCTray Integration

My CCTray integration for OctopusDeploy is now fully functional!

Check it out if you want CCTray to report the status of your OctopusDeploy builds.

You can find the source code on GitHub with an example web forms page that outputs the XML.

Sunday, September 28, 2014

Working with the Google Reseller API

I spent a few days trying to get this to work so it’s worth a write-up of what it takes to use the API from .NET.


  1. Create an Google Apps account in you can use to impersonate the client and get the data. You do that by going to for your Google Apps reseller account.
  2. Enable API Access by going to Security/API Reference and checking “Enable API access.”
  3. Create a new project in Google Developer Console. I called mine “ResellerAPI.”
  4. Configure the Reseller API to be available to your project by going to the “ResellerAPI” project/APIs and enabling “Google Apps Reseller API.”
  5. Create a service account credential under the “ResellerAPI” project/Credentials. You will need to download the P12 key, write down the client ID and the client email address.
  6. Back in the Google Apps admin console, enable client API access for the client ID you created in step 5. You do this by going to Advanced Settings/Mange API client access. You will add the client ID and the API scope “

Project Setup

  1. Create a new .NET project. I called mine GoogleApi.
  2. Open the Nuget package manager and install Google.Apis.Reseller.v1 with the command: install-package Google.Apis.Reseller.v1
  3. Update the Microsoft.BCL.Async package to the latest version with: install-package Microsoft.Bcl.Async

Variable Setup

We will create all the above settings a local private constants:

private const string ClientSertificatePath = @"The path to the certificate file from step 5";
private const string ClientSertificatePassword = "notasecret";
private const string ClientAccountEmail = "The client email address from step 5";
private const string ClientImpersonateUser = "Your Google Apps user from step 1";
private const string ApplicationName = "Reseller Sample";
private const int ServiceMaxResults = 100;

Service Setup

We will use a separate function to setup the service:

/// <summary>
/// Creates the reseller service object
/// with the provided client settings and certificate
/// </summary>
/// <returns></returns>
private ResellerService Setup()
    // Create a new certificate from the client certificate file
    var certificate = new X509Certificate2(ClientSertificatePath, ClientSertificatePassword, X509KeyStorageFlags.Exportable);

    // Create new credentials based on the certificate and the client settings
    var credentials = new ServiceAccountCredential(
       new ServiceAccountCredential.Initializer(ClientAccountEmail)
           // Set the scope of the request, AppOrderReadonly does not work here
           Scopes = new[] { ResellerService.Scope.AppsOrder },
           User = ClientImpersonateUser

    // Return a new service with the client credentials
    return new ResellerService(new BaseClientService.Initializer()
        HttpClientInitializer = credentials,
        ApplicationName = ApplicationName,

Get Subscriptions

A separate function will be used recursively to get a list of subscriptions:

/// <summary>
/// Gets a list of subscriptions
/// </summary>
/// <param name="service">The ResellerService object</param>
/// <param name="listOfSubscriptions">A list of Subscription to store the returned data</param>
/// <param name="nextPageToken">The string containing the next page token</param>
private void GetSubscriptions(ref ResellerService service, ref List<subscription> listOfSubscriptions, string nextPageToken)
    listOfSubscriptions = listOfSubscriptions ?? new List<subscription>();

    // Create the subscriptions list request
    var listResults = service.Subscriptions.List();

    // Set the max results and page token
    listResults.MaxResults = ServiceMaxResults;
    listResults.PageToken = !string.IsNullOrEmpty(nextPageToken) ? nextPageToken : string.Empty;

    // Execute the request
    var result = listResults.Execute();

    if (result.SubscriptionsValue != null)
        // Add all the subscriptions to the list

        // If the next page token exists
        if (result.NextPageToken != null)
            // Call yourself again passing the next page token
            GetSubscriptions(ref service, ref listOfSubscriptions, result.NextPageToken);

Putting it Together

The run function that will setup the service and get a list of subscriptions:

private void Run()
    // Setup the service
    var service = Setup();
    var listOfSubscriptions = new List<subscription>();

    Console.WriteLine("Getting a list of subscriptions...");
    GetSubscriptions(ref service, ref listOfSubscriptions, string.Empty);

    foreach (var s in listOfSubscriptions)
        Console.WriteLine(s.SubscriptionId + " - " + s.CustomerId);

    Console.WriteLine("Total: {0}", listOfSubscriptions.Count);

Downloads and Source Code

You can download all the working project from my Dropbox. Source code is on GitHub.

// //]]>