visual-studiovisual-studio-extensionsvsixvisual-studio-package

Visual Studio Custom Editor for Specific File


Context:

I'm creating custom project template for visual studio 2017 which works well. Inside this project template, I emit a file named "manifest.json".

I need to create custom editor\designer for the "manifest.json" file that's when the user double clicks this file in "Solution Explorer", it opens my custom editor.

I already found few articles on Microsoft Doc (like this one Create custom editors and designers) and found some GitHub examples about creating custom editors and custom designer (like this Editor_With_Toolbox, SingleFileGenerator, WPFDesigner_XML and Snippet Designer).

Problem:

Summary:

I want to implement visual studio custom editor\designer that run only for a specific file in my custom project template. How to achieve this?

Notes:


Solution

  • Finally after a lot of try and error approach supported with open source samples, I got solution to my problem in the following steps:

    1. Implement custom editor normally as in any of the samples posted in the question (like Editor With Toolbox).
    2. Inside the editor factory class (the class that implements IVsEditorFactory), inside the CreateEditorInstance function, you can make condition like this to limit the editor to JSON files with specific name:
    if (System.IO.Path.GetFileName(pszMkDocument).ToLower() != "manifest.json")
    {
        return VSConstants.VS_E_UNSUPPORTEDFORMAT;
    }
    
    1. To limit our custom editor to specific custom project we need to mark our target file with metadata (to know more about metadata, look for msbuild metadata) in the template project file (ProjectTemplate.csproj) as the following:
    <Content Include="manifest.json" >
        <IsWebExtensionManifest>true</IsWebExtensionManifest>
    </Content>
    
    1. To check for the metadata inside the editor factory, we will continue our work in the CreateEditorInstance function as the following:

      4.1 We already have these 2 parameters passed to the CreateEditorInstance function: (IVsHierarchy pvHier and uint itemid).

      4.2 Use these 2 parameters to obtain IVsBuildPropertyStorage of the parent project (some code examples exist online).

      4.3 Use this code to check for our mark metadata:

    buildPropertyStorage.GetItemAttribute(itemid, "IsWebExtensionManifest", out string propVal);
    if (!Convert.ToBoolean(propVal))
    {
        return VSConstants.VS_E_UNSUPPORTEDFORMAT;
    }
    

    Once I finish my custom project with this custom editor, I'll post its GitHub link for more clarity.