Visual Studio Custom Editor for Specific File

1.3k Views Asked by At

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:

  • Most of the articles, examples and documentations explain how to associate the custom editor with specific file extension (in my case I want to associate the editor with specific file "manifest.json" in a specific project).
  • The articles related to single file generator, they don't fit my solution because they speak about a file is edited in the designer and another file is emitted in the solution (like windows forms designer).

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:

  • The file to be associated in the custom editor must be named "manifest.json".
  • If there's a file named "manifest.json" in other project types, the standard editor should be executed not my custom editor.
1

There are 1 best solutions below

1
On BEST ANSWER

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.