How to build and run a simple custom tool
In this tutorial I am going to explain how to create a simple custom tool. I took the article Custom Tool Explained as a model, cutting out some distracting from understanding the subject things (like using reflection and registering assembly in the GAC).
I also found out by the series of trials and errors that in order to make the tool actually work you have to add some additional (not covered in the orginal article) keys into the registry. I got that information from the article called Custom Tool (Single File Generator) for Visual Studio 2015 which you may also find useful.
In this demo I am using Visual Studio 2015 running on Windows 10. So let's get hands dirty.
1. Launch Visual Studio as administrator.
2. Create a new project of type "Class Library". Name it "FirstTool".
3. Rename "Class1.cs" into "FTool.cs".
4. Go to Nuget Package Manager and install Microsoft.VisualStudio.Shell.Interop package.
5. Add reference to the System.Windows.Forms library to the project.
6. Make your FTool class look like this:

using System;
using System.Runtime.InteropServices;
using System.Text;
using System.Windows.Forms;
using Microsoft.VisualStudio.Shell.Interop;

namespace FirstTool
{
	[Guid("46DA4125-5E46-452E-AF9E-335324C3291D")]
	public class FTool : IVsSingleFileGenerator
	{
	    public int DefaultExtension(out string pbstrDefaultExtension)
	    {
		    pbstrDefaultExtension = ".txt";
		    return pbstrDefaultExtension.Length;
	    }

	    public int Generate(string wszInputFilePath, string bstrInputFileContents, string wszDefaultNamespace,
		    IntPtr[] rgbOutputFileContents, out uint pcbOutput, IVsGeneratorProgress pGenerateProgress)
	    {
		    try
		    {
			    string output = bstrInputFileContents + Environment.NewLine + "World";

			    byte[] bytes = Encoding.UTF8.GetBytes(output);
			    int length = bytes.Length;
			    rgbOutputFileContents[0] = Marshal.AllocCoTaskMem(length);
			    Marshal.Copy(bytes, 0, rgbOutputFileContents[0], length);
			    pcbOutput = (uint)length;
		    }
		    catch (Exception ex)
		    {
			    MessageBox.Show(ex.ToString());
			    pcbOutput = 0;
		    }
		    return 0;
	    }
	}
}

7. Run Developer Command Prompt as administrator. Launch guidgen.exe from it and generate a new Guid. Replace old Guid in attribute in front of FTool class with the Guid you just have generated.
8. Go to AssemblyInfo.cs file and set "ComVisible" to true.
9. Build solution.
10. Create on your disk a folder where you will permanently keep Custom Tool's dlls. In my case I will keep everything under C:\CustomTools\FirstTool folder. Copy the dlls that you have just built into this folder.
11. In Developer Command Prompt navigate to C:\CustomTools\FirstTool folder and register assembly for COM by running: C:\Windows\Microsoft.NET\Framework64\v4.0.30319\regasm.exe FirstTool.dll. If you are using 32-bit Windows, then the path to regasm.exe will be C:\Windows\Microsoft.NET\Framework\v4.0.30319\regasm.exe.
In order to unregister your tool run C:\Windows\Microsoft.NET\Framework64\v4.0.30319\regasm.exe /u FirstTool.dll or C:\Windows\Microsoft.NET\Framework\v4.0.30319\regasm.exe /u FirstTool.dll accordingly.
12. Add the necessary keys into the registry by running the following script:
            
Windows Registry Editor Version 5.00

[HKEY_CURRENT_USER\SOFTWARE\Microsoft\VisualStudio\14.0_Config\Generators\{FAE04EC1-301F-11D3-BF4B-00C04F79EFBC}\FTool]
@="Description of the tool"
"CLSID"="{46DA4125-5E46-452E-AF9E-335324C3291D}"
"GeneratesDesignTimeSource"=dword:00000001
"GeneratesSharedDesignTimeSource"=dword:00000001


[HKEY_CURRENT_USER\SOFTWARE\Microsoft\VisualStudio\14.0_Config\CLSID\{46DA4125-5E46-452E-AF9E-335324C3291D}]
"InprocServer32"="C:\\WINDOWS\\system32\\mscoree.dll"
"ThreadingModel"="Both"
"Assembly"="FirstTool, Version=1.0.0.0, Culture=neutral"
"CodeBase"="file:///C:\\CustomTools\\FirstTool\\FirstTool.dll"
"Class"="FirstTool.FTool"
             
            
Make sure that the .reg file that you are running has the correct encoding.
13. Run regedit.exe and make sure that the keys were successfully created:
14. Launch a new copy of Visual Studio (it's important because VS loads your custom tool into memory when it runs) and create a new "TestingFirstTool" Console Application.
15. Create a new file called "Hello.sql" and put "Hello" inside of it. The extension of this file can be anything you want. I am just making the point that it doesn't matter to what file the custom tool will be applied to.
16. Go to Hello.sql's file properties and set "Custom Tool" property to "FTool". Hit Ctrl+S on your keyboard to save the changes.
17. By now you should see a new file "Hello.txt" that was generated underneath the "Hello.sql" file. Now every time when you save the "Hello.sql" the "Hello.txt" will be regenerated. You can also run custom tool by right clicking on "Hello.sql" file and selecting "Run Custom Tool" option from the context menu. I still haven't figured out how to prevent the custom tool from running each time on save (i.e. forcing it to run only through context menu).
P.S. If you will be getting any errors trying to run your custom tool (like "Cannot find custom tool 'CustomToolName' on this system") go ahead and download the Procces Monitor tool. With its help you will see what and where Visual Studio is trying to find in registry in order to launch your custom tool. Most likely it cannot find some key and you will see what it is exactly.
Here is how you can configure the filter of the tool to see only what you really need: