コガネブログ

平日更新を目標に Unity や C#、Visual Studio、ReSharper などのゲーム開発アレコレを書いていきます

【Visual Studio 拡張機能作成】ソリューションを読み込んだらコマンドを有効にして、ソリューションが閉じたらコマンドを無効にする方法

概要

.vsct ファイルの「Button」に <CommandFlag>DefaultDisabled</CommandFlag> を追加して
コマンドがデフォルトで無効になるように設定します

<Buttons>
  <Button guid="guidCommand1PackageCmdSet" id="Command1Id" priority="0x0100" type="Button">
    <Parent guid="guidCommand1PackageCmdSet" id="MyMenuGroup" />
    <Icon guid="guidImages" id="bmpPic1" />
    <CommandFlag>DefaultDisabled</CommandFlag> <!-- ★追加 -->
    <Strings>
      <ButtonText>Invoke Command1</ButtonText>
    </Strings>
  </Button>
</Buttons>

コマンドクラスで OleMenuCommand クラスのインスタンスを作成して
BeforeQueryStatus イベントにコールバックを登録します

var commandService = ServiceProvider.GetService( typeof( IMenuCommandService ) ) as OleMenuCommandService;
if ( commandService == null ) return;

var menuCommandID = new CommandID( CommandSet, CommandId );
var menuItem = new OleMenuCommand( MenuItemCallback, menuCommandID );
menuItem.BeforeQueryStatus += new EventHandler( OnBeforeQueryStatus );
commandService.AddCommand( menuItem );

そして、BeforeQueryStatus イベントに登録する関数を下記のように定義します

private void OnBeforeQueryStatus( object sender, EventArgs e )
{
    var item = sender as OleMenuCommand;
    var service = ServiceProvider.GetService( typeof( DTE ) ) as DTE;
    var solution = service.Solution;

    item.Enabled = solution.IsOpen;
}

最後に、パッケージクラスに ProvideAutoLoad 属性を適用して
ソリューションを読み込んだ時、閉じた時にパッケージが読み込まれるようにします

[ProvideAutoLoad( UIContextGuids80.SolutionExists )] // ★追加
public sealed class Command1Package : Package

参考サイト様