Как зарегистрировать "пользовательский инструмент" в Visual Studio 2017, чтобы он работал?

Справочная информация: у нас есть пользовательский инструмент, который принимает ввод XML и генерирует вывод CS. Пользовательский инструмент должен зарегистрироваться в Visual Studio, чтобы он работал с этой версией Visual Studio.

Что мы сделали: мы сделали пользовательскую регистрацию инструмента в Visual Studio 2015, которая работает нормально. Но теперь проблема с Visual Studio 2017.

Проблема: До сих пор в моем исследовании я обнаружил, что до Visual Studio 2015 у VS были прямые записи в реестре, которые позволяли регистрировать инструмент, но с VS 2017 года Microsoft внесла изменения в способ хранения записей реестра ( хорошее чтение для понять изменения в VS2017).

Если я открою VS 2017 и попробую запустить пользовательский инструмент, то получу ошибку

Не удается найти пользовательский инструмент "Имя инструмента" в этой системе.

введите описание изображения здесь

Это очевидно, потому что пользовательский инструмент еще не зарегистрирован в VS 2017 для работы.

Я пытался следовать за этим парнем, который говорит, чтобы загрузить .bin подать в реестры, но он также говорит, что он отключает запуск VS 2017. Чтобы запустить VS, мы должны выгрузить куст. Исследования показывают, что файл.bin может находиться в разных местах в зависимости от типа установленного VS (корпоративный, профессиональный и т. Д.).

Кто-нибудь делал это раньше?

ТИА

2 ответа

Решение

Возможно, вам придется придерживаться другого подхода, создав расширение Visual Studio (VSIX), ниже я подробно объяснил его, надеюсь, это поможет.

Как создать пользовательский инструмент или генератор одного файла в Visual Studio 2017:

До VS2017 создание пользовательского инструмента требовало реализации интерфейса IVsSingleFileGenerator и код для регистрации и отмены регистрации пользовательского инструмента в системном реестре, но в VS2017 Microsoft изменила всю структуру реестра. Изменение заключается в том, что VS сделает записи реестра в частном реестре, чтобы системный реестр не перепутался. Если раньше записи в реестре делались в системном реестре, то теперь они сделаны для

C:\Users\ хуг \ AppData \ Local \ Microsoft \ VisualStudio \ 15.0_xx \ privateregistry.bin

Visual Studio 2017 также поддерживает тестирование вашего инструмента напрямую, запуская его из самой Visual Studio (F5), которая запускает другой экземпляр Visual Studio, который называется Visual Studio Experimental Instance, и ваш инструмент может быть протестирован в нем, поскольку он делает записи реестра в

C:\Users\ хуг \AppData\Local\Microsoft\VisualStudio\15.0_xxExp\privateregistry.bin

Выполните следующие шаги для создания пользовательского инструмента в VS2017:

  1. Нам нужно создать расширение VSIX
  2. Добавить новый пакет Visual Studio
  3. Воплощать в жизнь IVsSingleFileGenerator
  4. Добавьте код записи реестра
  5. Скомпилируйте и протестируйте инструмент, запустив его в VS2017
  6. Установите инструмент, дважды щелкнув созданный файл.VSIX

Мы создадим расширение / пользовательский инструмент в качестве примера с именем "CountLines", который будет считывать файл (со свойством Custom Tool, установленным в CountLines) и генерировать XML-файл, содержащий количество строк в файле. например <LineCount>1050</LineCount>

1. Создайте расширение VSIX. Чтобы создать расширение, вы должны установить инструменты расширения Visual Studio, которые включены в качестве дополнительной функции в настройке Visual Studio. Если он не установлен, вы также можете установить его, изменив настройки VS2017. Создайте новый проект VSIX (расширение Visual Studio), выбрав

Новый проект -> Расширяемость -> Проект VSIX

дать ему какое-то имя, например, "CountLinesVSIX".

2. Добавьте новый пакет Visual Studio. После создания проекта VSIX добавьте в него новый пакет Visual Studio, выбрав

Добавить -> Новый элемент -> Расширяемость -> Пакет Visual Studio

дать ему имя "CountLines.cs". В CountLines.cs нам нужно удалить существующий код и заменить его нашим кодом для IVsSingleFileGenerator реализация

3. Внедрите IVsSingleFileGenerator. Напишите свою собственную реализацию для интерфейса. IVsSingleFileGeneratorнаш пример кода, как показано ниже

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

namespace CountLinesVSIX
    {
    [PackageRegistration(UseManagedResourcesOnly = true)]
    [InstalledProductRegistration( "CountLines", "Generate XML with line count", "1.0")] 
    [Guid("202E7E8B-557E-46CB-8A1D-3024AD68F44A")]
    [ComVisible(true)]
    [ProvideObject(typeof(CountLines))]
    [CodeGeneratorRegistration(typeof(CountLines), "CountLines", "{FAE04EC1-301F-11D3-BF4B-00C04F79EFBC}", GeneratesDesignTimeSource = true)]
    public sealed class CountLines : IVsSingleFileGenerator
    {

        #region IVsSingleFileGenerator Members

        public int DefaultExtension(out string pbstrDefaultExtension)
        {
            pbstrDefaultExtension = ".xml";
            return pbstrDefaultExtension.Length;
        }

        public int Generate(string wszInputFilePath, string bstrInputFileContents,
          string wszDefaultNamespace, IntPtr[] rgbOutputFileContents,
          out uint pcbOutput, IVsGeneratorProgress pGenerateProgress)
        {
            try
            {
                int lineCount = bstrInputFileContents.Split('\n').Length;
                byte[] bytes = Encoding.UTF8.GetBytes("<LineCount>" + lineCount.ToString() + "</LineCount>" );
                int length = bytes.Length;
                rgbOutputFileContents[0] = Marshal.AllocCoTaskMem(length);
                Marshal.Copy(bytes, 0, rgbOutputFileContents[0], length);
                pcbOutput = (uint)length;
            }
            catch (Exception ex)
            {
                pcbOutput = 0;
            }
            return VSConstants.S_OK;
        }

        #endregion
    }
}

Нам нужно предоставить уникальный GUID для нашего расширения, такой как приведенный выше код [Guid("202E7E8B-557E-46CB-8A1D-3024AD68F44A")], GUID может быть создан из VS2017, выбрав "Инструменты -> Создать GUID". Выберите формат GUID в качестве формата реестра. Обратите внимание, что код GUID, упомянутый выше, без фигурных скобок.

[ComVisible(true)] требуется для COM Interops

[CodeGeneratorRegistration(typeof(CountLines), "CountLines", "{FAE04EC1-301F-11D3-BF4B-00C04F79EFBC}", GeneratesDesignTimeSource = true)] является атрибутом класса с кодом для регистрации инструмента. Параметры: GeneratorType, GeneratorName и GUID языка C#

Вы также можете получить из TemplatedCodeGenerator, который поддерживает пользовательское форматирование TextTemplate, что может потребовать некоторой дополнительной реализации кода.

4. Добавьте код записи реестра. Создайте новый файл класса с кодом ниже, назовите его CodeGeneratorRegistrationAttribute.cs

using System;
using System.Globalization;
using Microsoft.VisualStudio.Shell;

namespace CountLinesVSIX
{

    [AttributeUsage(AttributeTargets.Class, AllowMultiple = true, Inherited = true)]
    public sealed class CodeGeneratorRegistrationAttribute : RegistrationAttribute
    {
        private string _contextGuid;
        private Type _generatorType;
        private Guid _generatorGuid;
        private string _generatorName;
        private string _generatorRegKeyName;
        private bool _generatesDesignTimeSource = false;
        private bool _generatesSharedDesignTimeSource = false;

        public CodeGeneratorRegistrationAttribute(Type generatorType, string generatorName, string contextGuid)
        {
            if (generatorType == null)
                throw new ArgumentNullException("generatorType");
            if (generatorName == null)
                throw new ArgumentNullException("generatorName");
            if (contextGuid == null)
                throw new ArgumentNullException("contextGuid");

            _contextGuid = contextGuid;
            _generatorType = generatorType;
            _generatorName = generatorName;
            _generatorRegKeyName = generatorType.Name;
            _generatorGuid = generatorType.GUID;
        }

        /// <summary> 
        /// Get the generator Type 
        /// </summary> 
        public Type GeneratorType
        {
            get { return _generatorType; }
        }

        /// <summary> 
        /// Get the Guid representing the project type 
        /// </summary> 
        public string ContextGuid
        {
            get { return _contextGuid; }
        }

        /// <summary> 
        /// Get the Guid representing the generator type 
        /// </summary> 
        public Guid GeneratorGuid
        {
            get { return _generatorGuid; }
        }

        /// <summary> 
        /// Get or Set the GeneratesDesignTimeSource value 
        /// </summary> 
        public bool GeneratesDesignTimeSource
        {
            get { return _generatesDesignTimeSource; }
            set { _generatesDesignTimeSource = value; }
        }

        /// <summary> 
        /// Get or Set the GeneratesSharedDesignTimeSource value 
        /// </summary> 
        public bool GeneratesSharedDesignTimeSource
        {
            get { return _generatesSharedDesignTimeSource; }
            set { _generatesSharedDesignTimeSource = value; }
        }


        /// <summary> 
        /// Gets the Generator name  
        /// </summary> 
        public string GeneratorName
        {
            get { return _generatorName; }
        }

        /// <summary> 
        /// Gets the Generator reg key name under  
        /// </summary> 
        public string GeneratorRegKeyName
        {
            get { return _generatorRegKeyName; }
            set { _generatorRegKeyName = value; }
        }

        /// <summary> 
        /// Property that gets the generator base key name 
        /// </summary> 
        private string GeneratorRegKey
        {
            get { return string.Format(CultureInfo.InvariantCulture, @"Generators\{0}\{1}", ContextGuid, GeneratorRegKeyName); }
        }
        /// <summary> 
        ///     Called to register this attribute with the given context.  The context 
        ///     contains the location where the registration inforomation should be placed. 
        ///     It also contains other information such as the type being registered and path information. 
        /// </summary> 
        public override void Register(RegistrationContext context)
        {
            using (Key childKey = context.CreateKey(GeneratorRegKey))
            {
                childKey.SetValue(string.Empty, GeneratorName);
                childKey.SetValue("CLSID", GeneratorGuid.ToString("B"));

                if (GeneratesDesignTimeSource)
                    childKey.SetValue("GeneratesDesignTimeSource", 1);

                if (GeneratesSharedDesignTimeSource)
                    childKey.SetValue("GeneratesSharedDesignTimeSource", 1);

            }
        }

        /// <summary> 
        /// Unregister this file extension. 
        /// </summary> 
        /// <param name="context"></param> 
        public override void Unregister(RegistrationContext context)
        {
            context.RemoveKey(GeneratorRegKey);
        }
    }
}

Выше код будет убедиться, что ваши записи сделаны в личный реестр VS

5. Скомпилируйте и протестируйте инструмент, запустив его в VS2017. Вы можете добавить "Установить цели" в "source.extension.vsixmanifest", чтобы гарантировать, что ваше расширение поддерживает различные редакции VS2017. Запустите ваш инструмент в VS 2017, чтобы проверить, работает ли он должным образом. После запуска VSIX экспериментальный экземпляр Visual Studio установит расширение и зарегистрирует его в реестре "C:\Users\xyz\AppData\Local\Microsoft\VisualStudio\15.0_xxExp\privateregistry.bin". Вы можете увидеть установленное расширение, выбрав "Инструменты -> Расширения и обновления". Чтобы протестировать инструмент, нам нужно открыть фиктивный проект, выбрать файл в обозревателе решений, перейти к его свойствам и обновить свойство Custom Tool до "CountLines". Как только это будет сделано, VS запустит инструмент в фоновом режиме и сгенерирует вывод, в нашем примере он сгенерирует XML-файл под выбранным файлом. Кроме того, как только свойство Custom Tool установлено, вы можете щелкнуть правой кнопкой мыши файл и выбрать "Run Custom Tool"

6. Установите инструмент, дважды щелкнув по сгенерированному файлу.VSIX. После успешного тестирования попробуйте установить VSIX, который находится по адресу "имя_проекта /bin/debug". Установите VSIX, дважды щелкнув файл, следуя инструкциям по установке. Теперь ваш инструмент будет доступен для использования в VS2017. Использование инструмента аналогично, щелкните правой кнопкой мыши файл, для которого вы хотите запустить пользовательский инструмент, и выберите "Запустить пользовательский инструмент".

Если вы хотите удалить расширение, перейдите в "Инструменты -> Расширения и обновления -> выберите расширение" и нажмите "Удалить". Обратите внимание, что инструмент не будет удален, пока VS не закроется. После закрытия вы получите всплывающее окно для удаления, выберите "Изменить" для удаления.

Ну, во время исследования я получил ответ на эту проблему.

Решение:

  1. Мы должны загрузить файл.bin (через load hiv).
  2. Внесите изменения или отредактируйте корзину, чтобы зарегистрировать свой инструмент.
  3. Разгрузить улей.

Шаг № 1: Загрузите Улей.

а) Открыть реестр (regedit). Выберите узел HKEY_LOCAL_MACHINE,

б) Перейти к | Файл -> Загрузить куст

c) Выберите файл bin, который доступен по адресу -> %LocalAppData%\ Microsoft\ VisualStudio\ 15.0_'instance_id'\privateregistry.bin,

г) Введите ключевое имя. Это создаст новую ключевую запись в HKEY_LOCAL_MACHINE с вашим ключевым именем.

д) Вы можете проверить.bin файл на HKEY_LOCAL_MACHINE\YourKeyName\Software\Microsoft\VisualStudio\

Шаг № 2: Редактирование корзины: теперь вы можете зарегистрировать свой пользовательский инструмент, следуя тому же, как вы делали для других версий VS. Фактически единственной проблемой было получение ключей VS2017 в глобальном реестре, и это было решено с помощью шага № 1 выше.

Шаг № 3: Разгрузить Улей.

а) выберите свой ключ под HKEY_LOCAL_MACHINE,

б) Перейти к | Меню Файл

в) Разгрузить улей.

Другие вопросы по тегам