web-dev-qa-db-ja.com

「カスタムツール」をVisual Studio 2017またはVisual Studio 2019に登録して機能させるにはどうすればよいですか?

背景:xml入力を受け取り、cs出力を生成する カスタムツール があります。そのバージョンのVisual Studioで動作させるために、Visual Studioでカスタムツール 登録が必要

行ったこと:カスタムツール登録 をVisual Studio 2015で実行しましたが、正常に機能しています。しかし、今問題はVisual Studio 2017にあります。

問題:これまでのところ、Visual Studio 2015まで、VSには、ツールの登録を許可する直接のレジストリエントリがありましたが、VS 2017からのものでした、Microsoftはレジストリエントリの格納方法に変更を加えました( VS2017での変更点を理解するためによく読んでください )。

VS 2017を開いてカスタムツールを実行しようとすると、エラーが発生する

このシステムでカスタムツール "ツール名"が見つかりません。

enter image description here

カスタムツールが動作するようにVS 2017にまだ登録されていないため、これは明らかです。

私はフォローしようとした this guy これは.binファイルをレジストリに追加しますが、VS 2017の起動が無効になるとも述べています。VSを起動するには、Hiveをアンロードする必要があります。調査によると、.binファイルは、インストールされているVSのタイプ(エンタープライズ、プロなど)に基づいて別の場所にある可能性があります。

誰かがこれを以前にやったことがありますか?

TIA

7
Amnesh Goel

Visual Studio拡張機能(VSIX)を作成して、ここで別のアプローチに従う必要があるかもしれません。以下で詳しく説明しますが、役立つことを願っています。

Visual Studio 2017でカスタムツールまたは単一ファイルジェネレーターを作成する方法:

VS2017より前にカスタムツールを作成するには、インターフェイスIVsSingleFileGeneratorを実装する必要があり、システムレジストリでカスタムツールを登録および登録解除するためのコードが必要でしたが、VS2017では、Microsoftはレジストリ構造全体を変更しました。変更点は、VSがレジストリエントリをプライベートレジストリに作成するため、システムレジストリが混乱しないようにすることです。以前はレジストリエントリがシステムレジストリに作成されていましたが、現在は

C:\ Users\xyz\AppData\Local\Microsoft\VisualStudio\15.0_xx\privateregistry.bin

Visual Studio 2017は、Visual Studio自体(F5)から実行することによるツールの直接テストもサポートしています。これにより、Visual Studioの別のインスタンスVisual Studio Experimental Instanceが起動し、ツールをテストできます。レジストリエントリを作成します

C:\ Users\xyz\AppData\Local\Microsoft\VisualStudio\15.0_xxExp\privateregistry.bin

VS2017でカスタムツールを作成するには、以下の手順に従ってください:

  1. VSIX拡張を作成する必要があります
  2. 新しいVisual Studioパッケージを追加する
  3. 実装IVsSingleFileGenerator
  4. レジストリエントリコードを追加する
  5. VS2017で実行してツールをコンパイルおよびテストする
  6. 生成された.VSIXファイルをダブルクリックしてツールをインストールします

「カスタムツールプロパティがCountLinesに設定されている」ファイルを読み取り、ファイル内の行数を含むXMLファイルを生成する「CountLines」という名前の拡張/カスタムツールを例として作成します。例えば_<LineCount>1050</LineCount>_

1。 VSIX拡張機能を作成する拡張機能を作成するには、Visual Studioセットアップのオプション機能として含まれているVisual Studio Extensibility Toolsをインストールしておく必要があります。インストールされていない場合は、VS 2017セットアップを変更してインストールすることもできます。選択して新しいVSIX(Visual Studio Extension)プロジェクトを作成します

新しいプロジェクト->拡張性-> VSIXプロジェクト

「CountLinesVSIX」のような名前を付けます。

2。新しいVisual Studioパッケージを追加する VSIXプロジェクトが作成されたら、次を選択して新しいVisual Studioパッケージを追加します

追加->新しいアイテム->拡張性-> Visual Studioパッケージ

「CountLines.cs」という名前を付けます。 _CountLines.cs_では、既存のコードを削除し、IVsSingleFileGenerator実装のコードに置き換える必要があります

。 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("202E7E8B-557E-46CB-8A1D-3024AD68F44A")]のように、拡張に一意のGUIDを提供する必要があります。GUIDは、VS2017から"ツール-> GUIDの作成"。レジストリフォーマットとしてGUIDフォーマットを選択します。上記のGUIDのコードには中括弧がないことに注意してください。

COM相互運用機能には[ComVisible(true)]が必要です

[CodeGeneratorRegistration(typeof(CountLines), "CountLines", "{FAE04EC1-301F-11D3-BF4B-00C04F79EFBC}", GeneratesDesignTimeSource = true)]は、ツールを登録するためのコードを持つクラス属性です。 GeneratorType、GeneratorName、およびC#言語のGUIDであるパラメーター

カスタムTextTemplateフォーマットをサポートする "TemplatedCodeGenerator"から派生させることもできます。これには、追加のコード実装が必要になる場合があります。

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」に登録します。インストールされている拡張機能は、「ツール->拡張機能と更新」を選択して確認できます。ツールをテストするには、ダミープロジェクトを開き、ソリューションエクスプローラーでファイルを選択し、そのプロパティに移動して、カスタムツールプロパティを "CountLines"に更新します。これが完了すると、VSはツールをバックグラウンドで実行して出力を生成します。この例では、選択したファイルの下にxmlファイルを生成します。または、カスタムツールプロパティを設定したら、ファイルを右クリックして[カスタムツールの実行]を選択できます。

6。生成された.VSIXファイルをダブルクリックしてツールをインストールしますテストが成功したら、場所「projectName/bin/debug」にあるVSIXをインストールしてみてください。ファイルをダブルクリックしてVSIXをインストールし、インストール手順に従います。これで、VS2017でツールを使用できるようになります。ツールの使用も同様です。カスタムツールを実行するファイルを右クリックし、[カスタムツールの実行]を選択します。

拡張機能をアンインストールする場合は、[ツール]-> [拡張機能と更新]-> [拡張機能を選択]に移動し、[アンインストール]をクリックします。 VSを閉じるまで、ツールはアンインストールされないことに注意してください。閉じると、アンインストールするポップアップウィンドウが表示されます。[変更]を選択してアンインストールします。

19
Siddhesh Parab

さて、研究中に、私はこの問題の答えを得ました。

ソリューション:

  1. (load hivを使用して).binファイルをロードする必要があります。
  2. 変更を加えるか、ビンを編集してツールを登録します。
  3. ハイブをアンロードします。

ステップ#1:ハイブを読み込む

a)レジストリを開きます(regedit)。ノードHKEY_LOCAL_MACHINEを選択します。

b)|に移動しますファイル->ハイブの読み込み

c)-> %LocalAppData%\ Microsoft\ VisualStudio\ 15.0_'instance_id'\privateregistry.binにあるbinファイルを選択します。

d)キー名を入力します。これにより、HKEY_LOCAL_MACHINEに新しいキーエントリがキー名で作成されます。

e)HKEY_LOCAL_MACHINE\YourKeyName\Software\Microsoft\VisualStudio\で.binファイルを確認できます

enter image description here

ステップ#2:binを編集します:これで、他のVSバージョンの場合と同じ方法でカスタムツールを登録できます。実際、唯一の問題は、VS2017キーをグローバルレジストリに取得することでした。これは、上記の手順1を使用して解決されます。

ステップ#3:ハイブをアンロードします。

a)HKEY_LOCAL_MACHINEでキーを選択します。

b)|に移動しますファイルメニュー

c)ハイブをアンロードします。

enter image description here

3
Amnesh Goel