VisualStudioのビルド成功時にメモ帳を起動する
おいVSIX
Visual Studioの拡張機能を少しずつ作ってる。なんもわからん
開発対象にしてるのはVS2017
Visual Studioのビルド成功時にメモ帳を起動する
今回はビルド成功時に発火するイベントを用いて色々するやつ。ビルド成功したときにメモ帳が出て何がうれしいんだ?って感じだけど分かりやすい例としてね
めちゃくちゃ分かりやすいリファレンス(怒)はここ
BuildEventsClass Class
OnBuildDone/Beginイベント
OnBuildDone
はビルドが終了
したときに発火するイベントで、OnBuildBegin
はビルドが始まった
ときに発火するイベント。まあそのままですね
この二つに登録できるメソッドは第一引数にvsBuildScope
列挙型と第二引数にvsBuildAction
列挙型を持ってるやつだけ。つまり以下みたいなやつ
private void OnBuildDoneEvent(vsBuildScope scope,vsBuildAction action){ //なんかの処理 }
vsBuildScope
列挙型はリファレンスによると Represents the scope of the build.
らしい。ふーんなるほどねすべて理解した。それとvsBuildAction
列挙型は同リファレンスによるとRepresents the type of build action that is occurring, such as a build or a deploy action.
らしい。なるほどなるほど
こういうのはインテリセンス見たほうがはやいんですよ
vsBuildScope
はどうやらバッチビルドなのかソリューションのビルドなのかプロジェクトのビルドなのかを示してるらしい。そのままだったw
vsBuildAction
はどんなビルドだったのかが分かるらしい。これもそのままだったw
ていうかよくみたらビルドメニューのドロップダウンと一緒だった
OnBuildProjConfigDone/Beginイベント
こいつらはOnBuildDone/Begin
とほぼ同じタイミング(こっちのが先)で発生するが、ソースコードが変更されたなどでビルドし直さないといけないときにしか発生しない。つまり
こんな風にビルド時[出力ウインドウ]
に正常終了が出てる時しか発火しない。1文字もソースを変更せずにビルドしたときは変更不要になるのでこのイベントは起きない
これに登録できるメソッドは引数が結構多いから下を見てくれ
private void OnBuildProjConfigDoneEvent( string Project, string ProjectConfig, string Platform, string SolutionConfig, bool Success ) { //挟みこみたい処理 }
割と引数の名前が分かりやすいので何が入ってるかわかる。個人的に重要だと思ってるのは最後のbool
値。変数名からわかると思うけどSuccess
にはビルドが成功したかが入ってる。今回はこれがtrue
の時にメモ帳を起動すればOKということ
というわけでビルド成功時にメモ帳を起動したいなら
private void OnBuildProjConfigDoneEvent( string Project, string ProjectConfig, string Platform, string SolutionConfig, bool Success ) { if(!Success) return; new System.Diagnostics.Process { StartInfo = { FileName = "notepad.exe" } }.Start(); }
たぶんこんな感じになる
イベントハンドラを登録する
作ったメソッドをイベントハンドラとして登録して実際に動かしたい
上4つのイベントはEnvDTE.BuildEvents
インターフェイスにあるのでそれをどこからか探してくる必要がある。これにはPackage
クラスを継承しているクラスでGetService()
メソッドをつかってEnvDTE.DTE
インターフェイスを取得してそこから~~・・・・・文章書くのも難しいのでコードを張るね
protected override void Initialize() { var dte = (DTE)GetService(typeof(DTE)); //<--DTEインターフェイス取得 //dteを辿って OnBuildProjConfigDoneにハンドラ登録する。 dte.Events.BuildEvents.OnBuildProjConfigDone+=OnBuildProjConfigDoneEvent; }
VSIXを作るとコンストラクタの代わりに上みたいなメソッドを書くのでそこで登録すればいいと思うんだけど、実はこれではダメなんですよ
BuildEventsを持っておかないとダメ
ぼくもこれで動くと思ってたがうんともすんとも言わなくて泣いた。でも色々調べてたら下のにたどり着いた
social.msdn.microsoft.comhttps://social.msdn.microsoft.com/Forums/vstudio/en-US/33ab218f-3e7b-4dd9-b2a2-d5df04fefa6f/why-is-onbuilddone-event-not-firing?forum=vsx
どうやらPackage
クラスの継承先で参照を持ってないとダメらしい。VS2017のテンプレで作成したなら{ProjectName}Package.sc
ってソースだ(たぶん)
なので
public BuildEvents BuildEvent {get;set;} protected override void Initialize() { var dte = (DTE)GetService(typeof(DTE)); //<--DTEインターフェイス取得 //dteを辿ってBuildEvents取得 this.BuildEvents=dte.Events.BuildEvents; //はい this.BuildEvents.OnBuildProjConfigDone+=OnBuildProjConfigDoneEvent; }
これでOK
おっ起動したな
OnBuildDoneのときもメモ帳起動したい
今のままだとソースが変更されていて、新たにビルドしたときしかメモ帳が起動しないのは簡単にわかると思う。
ぼくは変更不要の時もメモ帳起動してほしかったのでOnBuildDone
にも登録したかったけど二重起動しちゃうし、そもそもOnBuildDone
は失敗時にも発火するのでダメ!ぼくは成功時だけがいいの!
まあでもこれはbool
をフィールドに持っていれば済む話で
private bool lastStatus = true; private void OnBuildDoneEvent(vsBuildScope sc,vsBuildAction ac){ if(lastStatus) WakeNotepad(); } private void OnBuildProjConfigDoneEvent(/* 略 */){ lastStatus=Success; } private void WakeNotepad() => new System.Diagnostics.Process { StartInfo = { FileName = "notepad.exe" } }.Start();
上にも少し書いたけどOnBuildDone
はOnBuildProjConfigDone
より後に発火するのでこうやって書ける
これをそれぞれのイベントに登録すればおわり!
BuildEvents
を持っておかないとだめっていう罠にどっぷりハマって死んでいたけど、これが分かってしまえば他のイベントでも同じようにすることになるのでやった~~~という感じですね
ちなみに他のイベントをまとめたクラスを作っておくとPackage
クラスから参照を渡すだけでいいので楽です
今回はここまで