Creating a Custom Tool (Single File Generator) for Visual Studio 2010

A Single File Generator or “Custom Tool” is a COM “extension” for Visual Studio that takes a project file as input, and spits out some code. (One example is the .settings files) Visual Studio automatically includes the code in your project, and updates it every time you save.

I developed a tool that reads an Office 2010 Ribbon XML file and produces an interface will all the callbacks in your file (because implementing callback signatures is a bear).

Unfortunately, Microsoft’s documentation on the subject is incomplete and obsolete. If you search the web, you will find contradictory information…
I didn’t want my assembly in the GAC, nor did want to have to register the COM object globally. I didn’t want to create a setup project, or use any fancy generated code… I just wanted it to work.

So here are some tips that should get you going.

  1. First of all, there is no need to use the Visual Studio extensibility project template for this. Just create a standard Class Library in the .NET language of your choice.
  2. Add a reference to Microsoft.VisualStudio.Shell.10.0 and Microsoft.VisualStudio.Shell.Interop to your project. (If you do not have these, you probably need to download the Visual Studio 2010 SP1 SDK)
  3. In the Project Properties, in the Application tab, click “Assembly Information…” and check the “Make Assembly COM Visible” box.
  4. Do NOT select “Register for COM interop” on the Build tab
  5. On the signing tab, check sign the assembly, and select or create a key
  6. Add the following using statements to your class file:
    using System.Runtime.InteropServices;
    using Microsoft.VisualStudio.Shell.Interop;
    using Microsoft.VisualStudio;
    
  7. Add the ComVisible attribute
  8. Add a Guid to the class (use the Tools Menu-> Create GUID and select Item 5 for c#, item 6 for vb.net, hit copy)
  9. Make your class implement the IVsSingleFileGenerator interface.
  10. It should look like this:
        [ComVisible(true)]
        [Guid("FAKEGUID-FFF6-4FF3-FFF7-FFFFRFRFRF45")]
        public class Generator : IVsSingleFileGenerator
        {
    
  11. DO NOT USE THIS GUID. YOU MUST GENERATE YOUR OWN
  12. Implement the IVsSingleFileGenerator interface’s two methods – Generate and DefaultExtension (see the documentation for more details)
  13. Build it!
  14. Now for the part where the documentation falls apart – registering and using this bad boy.

  15. The easiest way to register this is using the Visual Studio local registry at HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\VisualStudio\10.0
    Note: on 32-bit systems, this may be at HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\10.0 – I am using the 64-bit
    There should be plenty of sub-keys under this key. If there are not, perhaps you need to look in a different version, or bit-ness
  16. First, you need to add the COM information like so
    Windows Registry Editor Version 5.00
    
    [HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\VisualStudio\10.0\CLSID\{FAKEGUID-FFF6-4FF3-FFF7-FFFFRFRFRF45}]
    "InprocServer32"="C:\\Windows\\SysWOW64\\mscoree.dll"
    "ThreadingModel"="Both"
    "Class"="DemoSFGen.Generator"
    "Assembly"="DemoSFGen, Version=1.0.0.0, Culture=neutral, PublicKeyToken=faketokenfffff88"
    "CodeBase"="file:///C:\\Users\\username\\Documents\\Visual Studio 2010\\Projects\\sfgen\\sfgen\\bin\\Debug\\sfgen.dll"
    

    Replace the GUID after CLSID with the GUID you generated earlier; replace the Class with your Namespace.ClassName; replace Assembly with the information from your dll (I used ILSpy – I’m sure there’s an easier way); replace CodeBase with the full path to your dll.

  17. Next, add the registry info to tell Visual Studio about the Generator:
    Windows Registry Editor Version 5.00
    
    [HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\VisualStudio\10.0\Generators\{FAE04EC1-301F-11D3-BF4B-00C04F79EFBC}\DemoSFGen]
    "CLSID"="{FAKEGUID-FFF6-4FF3-FFF7-FFFFRFRFRF45}"
    "GeneratesDesignTimeSource"=dword:00000001
    @="Nice Name For your Generator"
    

    The GUID after \Generators\ corresponds to the languages in Visual Studio. See the docs for registering single file generators for a couple (or have a look in the registry).
    The Key name under the language guid (DemoSFGen in this case) is (I believe) how you will refer to the Custom Tool
    The value of CLSID needs to match your generated GUID

  18. Run Visual Studio, open a (different) project, and select an appropriate input file (text, xml, etc) In the properties for the file, add the name of the Custom Tool (“DemoSFGen”).
  19. Right click on the file, and select “Run Custom Tool”
  20. If everything worked, you will now be able to expand the file, and see your generated source underneath it. If there was a problem, Visual Studio may or may not display an error…

I know that Custom Tools aren’t the most often created things in the world, but hopefully these steps can at least get you up and running when you do try.

3 thoughts on “Creating a Custom Tool (Single File Generator) for Visual Studio 2010

  1. Hey,

    Thanks so much. I’ve finally got this working. I’ve been trawling for hours to get this working for VS2010. So glad I stumbled on this link.

  2. Hi Jason, could you share your project as a download ?
    I thought I was following your explanations to the point, but I must be missing some detail…
    VS keeps telling me it cannot find the generator :-((

    Thx for your views / download.

  3. Unfortunately, a project file is unlikely to help. The registry entries are the hard part – and are the most likely cause of your problems.

    Here are some things to check:
    1. In the two registry parts, you need to replace the fake guid with your own generated guid once in each part
    2. If you are using 32-bit windows, you will need to change the registry path for both parts, as well as the path to mscoree.dll
    3. Make sure the Assembly string value matches that of your compiled assembly (including the public token)
    4. Make sure the path to your dll is correct – and has double “\\” in the .reg file.
    5. If you are using VB, you will need to change the generator GUID in the second registry peice (the guid after Generators\) to {164b10b9-b200-11d0-8c61-00a0c91e29d5}

    Let me know if this doesn’t help – I could probably whip up a tool to generate the .reg files

Leave a Reply