Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Custom Tool (Single File Generator) for Visual Studio 2015

0.00/5 (No votes)
30 Aug 2015 1  
A Skeleton of a Single File Generator: Create, Register, Apply

Introduction

I have found a few descriptions on the internet on how to write a Custom Tool (Single File Generator) for Visual Studio but - mainly - the registration process had been an obstacle for me. Finally, I have come to a good point in my learning curve, and I am writing it up here all together for the community.

Please note: The tool itself is a skeleton, it does not do anything useful; it does not produce any text and returns an error message immediately. However, it is shown here how to develop, register and use a custom tool for Visual Studio 2015.

Prerequisites

I am using the Community edition of Visual Studio 2015. The VS installation must contain the "Visual Studio Extensibility Tools" (the VS SDK in former VS releases). If the Extensibility Tools are not installed yet, you can do so by modifying your current VS2015 installation.

01 VS2015 Installation Mododification

Part 1: Creation of the Single File Generator

Step 1: Create the Tool Project

Launch Visual Studio as Administrator. This is important or VS will not be able to copy the compiled and built tool into the "Program Files" folder.

Create a new Class Library Project:

/02_Create_Class_Library_Project.png

Go into the project Properties, select tab “Application” then go to the “Assembly Information”. Select the checkbox “Make assembly COM-Visible”, ignore the GUID shown there:

1023337/03_Tool_Assembly_Properties.png

Step 2: Project Property Settings

Go into the Solution Explorer and add the following references:

  • Microsoft.VisualStudio.Shell.14.0
  • Microsoft.VisualStudio.Shell.Interop

These references are found in the References Manager under “Assemblies” | “Extensions” - but only if VS had been configured to contain the “Visual Studio Extensibility”. Other references can be added or removed as required:

1023337/04_Project_Property_Settings.png

Step 3: Create Tool GUID

VS has a built-in GUID generator which is launched from the menu “TOOLS | Create GUID”:

1023337/05_Create_Tool_GUID_-_1.png

The dialog which pops up allows selection of a GUID format; the best format for our purposes is the “Registry Format” which requires only minimal modifications when pasting the new GUID into the several required locations. The new GUID is created after a click on button “New GUID”.

1023337/06_Create_Tool_GUID_-_2.png

Step 4: Coding and Building of the Tool

Create a single file, e.g. “ToolBase.cs”; all other source files which had been created with creation of the project can be removed. This file contains now the code for a (formally) complete tool:

using System;
using Microsoft.VisualStudio;
using Microsoft.VisualStudio.Shell.Interop;
using System.Runtime.InteropServices;


namespace MyTool
{
  // use the GUID from "Create GUID" without the curly braces
  [Guid("FCA4E6F2-6065-46E4-BCF7-2A62DDBF42AC")]
  public class ToolBase : IVsSingleFileGenerator
  {
    public int DefaultExtension (out string InputfileRqExtension)
    {
      InputfileRqExtension = ".txt"  // the extension must include the leading period
      return VSConstants.S_OK; // signal successful completion
    }


  public int Generate (string wszInputFilePath, string bstrInputFileContents, string wszDefaultNamespace,
    IntPtr[] rgbOutputFileContents, out uint pcbOutput, IVsGeneratorProgress pGenerateProgress)
    {
      pcbOutput = 0;  // no output is being generated
      return VSConstants.S_FALSE;  // force an error message
    }
  }
}

The is the most simple version of such a tool I can think of. It accepts an input file which must have the extension ".txt" (method "DefaultExtension"). However, method "Generate" which has to read the input file and produce data on output does immediately return an error message.

Note that the GUID which leads the class declaration is the GUID we had just created with the GUID tool. Now build the project but keep in mind that the tool is only formally acceptable but would throw an exception if you attempt to run it. But it should be good enough to proceed to registration of the tool.

Step 5: Copy the Tool DLL to a Persistent Location

To make the tool available for other projects (and for the Test Project which needs to be done later), we must copy it into some persistent place, e.g. "C:\Program Files\MyTool\". This step can be automated in VS and executed after a successful build. Please note that the copy command fails if the folder “C:\Program Files\VSTools” does not exist; so we have to create that folder manually before we run the first build with this copy command.

1023337/07_Copy_Tool_to_Persistent_Loc.png

Step 6: Register the Tool DLL in the System

The tool DLL must now be registered in order to make it "executable". This is done via Command Line which must be launched with admin privileges and must be done only after the first build or after the DLL name or (persistent) path have changed. We enter the following command:

C:\Windows\Microsoft.Net\Framework\v4.0.30319\regasm.exe /codebase "C:\Program Files\VSTools\MyTool.dll"

The target folder in the “Program Files” is the one we had created before we started the first build run; “MyTool.dll” is the name of the DLL we create in every build run. Feel free to change names according to your own requirements.

My attempt to use the regasm resulted in a warning:

RA0000: Registering an unsigned assembly with /codebase can cause your assembly to interfere 
with other applications that may be installed on the same computer. The /codebase switch is intended 
to be used only with signed assemblies. Please give your assembly a strong name and re-register it.
Types registered successfully

(I do not know about possible side effects of this warning, but since the types have been registered successfully, I will ignore this message and continue. Refer to “How to: Sign an Assembly with a Strong Name”).

Step 7: Register the Tool in Visual Studio 2015 IDE

Another one-time step is the installation of the tool in the VS IDE environment. The easiest way to accomplish this is the creation and execution of a text file which has the extension “.reg” and contains the following text:

Windows Registry Editor Version 5.00

;  Here: use the CLSID from the tool class
[HKEY_CURRENT_USER\SOFTWARE\Microsoft\VisualStudio\14.0_Config\CLSID\{FCA4E6F2-6065-46E4-BCF7-2A62DDBF42AC}]

"InprocServer32"="C:\\Windows\\System32\\mscoree.dll"
"ThreadingModel"="Both"

;  Here: use namespace name and class name of the tool
"Class"="MyTool.ToolBase"

;  Here: use assembly name from tool properties, assembly version info, 
and culture info from the assembly settings
"Assembly"="MyTool, Version=1.0.0.0, Culture=neutral"

;  Here: use the path to the DLL file  (duplicate the backslashes)
"CodeBase"=file:///C:\\Program Files\\VSTools\\MyTool.dll
;  Here: The GUID refers to usage of the tool in C# assemblies (do not change); 
use the namespace name of the tool
[HKEY_CURRENT_USER\Software\Microsoft\VisualStudio\14.0_Config\Generators\{FAE04EC1-301F-11D3-BF4B-00C04F79EFBC}\MyTool]

;  Here: use the CLSID from the tool class
"CLSID"="{FCA4E6F2-6065-46E4-BCF7-2A62DDBF42AC}"
"GeneratesDesignTimeSource"=dword:00000001

Note: It may happen that the registry editor rejects to merge this file into the registry (Message: “The specified file is not a registry script”). This may be caused by an invalid encoding of this file. The best way to overcome this situation is to export some small entry from the registry and paste the above text into that file. The new tool is now complete and ready to run; we can close this project.

Part 2: Formal Test of the Single File Generator

Step 1: Create the Test Project and a Test File

Restart Visual Studio normally with a standard project; we do not need admin privileges. Create a test file with the extension “.txt” required by the above tool, and we are ready to request that this file shall be read by the new tool and create some output from that.

The test file in this example is named “TestFile.txt”; it contains just a few random characters.
(Bear in mind that the tool does not really execute any meaningful operations yet.)

Step 2: Allocate the Test Tool to the Test File

Go into the Solution Explorer and open the properties of the test file:

1023337/10_Allocate_Test_Tool.png

Change the properties settings to the following:

  • Build Action: Content
  • Copy to Output Directory: Do not copy
  • Custom Tool: TestTool
  • ("TestTool" is the namespace name of the new tool which had been registered previously)

1023337/11_Allocate_Test_Tool_-_2.png

Step 3: Test Run Using the New Tool

An attempt to execute a build for the project, including the test file handled by our new custom tool should result in the following message:

"The custom tool 'MyTool' failed.  The method or operation is not implemented."

That is ok since the tool throws a NotImplementedException. Though, Visual Studio comes back with the message “Build succeeded”; I would consider this a bug.

We are now ready to go back to the development of the tool and make it perform more meaningful operations.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here