Visual Studio 2005 で "ビルド正常終了" / "ビルド失敗" のサウンドイベントを利用する方法

というわけで、マクロ書きました。えぇ書きましたとも。普段は VC しかいじってない身で VB 書いたり、Win32API をダイレクトに使っている身なのに .NET Framework とかいじって必死になってみましたが、書いてみましたよ! つ、疲れた… orz


でまぁ、マクロの中にサウンドファイル名埋め込みでも良いとは思ったのですが(開発者しか使わないだろうから)、レジストリから値を引っ張ってくるサンプルコードもあったので、Visual Studio 2003 の値を継承するような形にしてみました。

ご利用を希望の方は こちらよりDownLoad して

  1. レジストリファイルの適用
  2. マクロをコピペ
  3. コンパネから音の設定

をすればOKです。(多分)

なおオマケ機能として、VC6の頃にあった「ビルド警告」がこっそり復活してます! 懐かしい〜

以下サンプルコード



    ' ------------------------------------------------------
    ' Visual Studio 2005 で サウンドイベントが(多分バグの為に)
    ' 鳴らない問題を解決します。
    '
    ' ver            : 1.00.0.060706
    ' 対応           : Visual Studio 2005
    ' 作者           : いろきゅう
    ' 必要なファイル : vs2005_sound_events.reg
    ' 種別           : フリーソフト
    ' ライセンス     : 適当で
    ' ------------------------------------------------------

    ' ------------------------------------------------------
    ' ------------------------------------------------------
    ' ------------------------------------------------------
    '
    '
    '   * VS2005 サウンドイベント追加マクロ - 利用の仕方 *
    '
    '
    ' 1.  どうにかこうにか頑張って "マクロIDE" を起動します。
    '
    ' 2.  "プロジェクトエクスプローラ" から "EnviromentEvents"
    '     と言うファイルを頑張って開きます。
    '
    ' 3.  #Region で隠されているコードの下に、このテキストファ
    '     イルを丸ごと頑張ってコピー&ペーストします。 
    '
    ' 4.  付属のレジストリファイル "vs2005_sound_events.reg" を
    '     頑張ってダブルクリックし、値をレジストリに追加します。
    '
    ' 5.  [Windows キー] + [R] を押して、出てきたダイアログに
    '     "sndrec32" と入力し、頑張ってOKを押します。
    '
    ' 6.  マイクを用意し、サウンドカードの端子に頑張って接続
    '     します。ホコリがホコリが。
    '
    ' 7.  おもむろにレコードボタンを押して歌います。
    '     頑張ってください。
    '
    ' 8.  頑張れたらファイルを保存し、終了させます。
    '
    ' 9.  コントロールパネル -> サウンドとマルチメディア を頑
    '     張って開きます。
    '
    ' 10. "Microsoft Development Environment" の項目より、先ほ
    '     ど録音した Wave ファイルを頑張って割り当てます。
    '
    ' 11. 自分の声って意外と頑張れないよね。
    '
    '
    ' 以上のステップが *必需* になります。
    '
    ' ------------------------------------------------------
    ' ------------------------------------------------------
    ' ------------------------------------------------------

    '-------------------------------------------------------
    ' ファイル名、ソースコードに埋め込みの場合
    ' 下の3行コメントアウト外してちょ
    '-------------------------------------------------------
    'Private ReadOnly strFileNameSucceeded As String = "c:\WINNT\Media\ir_begin.wav"
    'Private ReadOnly strFileNameWarning As String = "c:\WINNT\Media\ir_end.wav"
    'Private ReadOnly strFileNameFailed As String = "c:\WINNT\Media\ir_inter.wav"


    '-------------------------------------------------------
    ' レジストリから VS2003 の設定を引っ張ってくる場合
    ' 下の3行コメントアウト外してちょ
    '-------------------------------------------------------
    Private ReadOnly strFileNameSucceeded As String = My.Computer.Registry.GetValue("HKEY_CURRENT_USER\AppEvents\Schemes\Apps\devenv\VS_BuildSucceeded\.current", "", "").ToString()
    Private ReadOnly strFileNameWarning As String = My.Computer.Registry.GetValue("HKEY_CURRENT_USER\AppEvents\Schemes\Apps\devenv\VS_BuildWarning\.current", "", "").ToString()
    Private ReadOnly strFileNameFailed As String = My.Computer.Registry.GetValue("HKEY_CURRENT_USER\AppEvents\Schemes\Apps\devenv\VS_BuildFailed\.current", "", "").ToString()


    '-------------------------------------------------------
    ' サウンドのプロパティ を利用して VS2005 の設定を新規に追加した場合…
    ' …と思ったけど結局役に立たない事に気づいたのでボツ
    ' 下の3行コメントアウト外してちょ
    '-------------------------------------------------------
    'Private ReadOnly strFileNameSucceeded As String = My.Computer.Registry.GetValue("HKEY_CURRENT_USER\AppEvents\Schemes\Apps\devenv8\VS_BuildSucceeded\.current", "", "").ToString()
    'Private ReadOnly strFileNameWarning As String = My.Computer.Registry.GetValue("HKEY_CURRENT_USER\AppEvents\Schemes\Apps\devenv8\VS_BuildWarning\.current", "", "").ToString()
    'Private ReadOnly strFileNameFailed As String = My.Computer.Registry.GetValue("HKEY_CURRENT_USER\AppEvents\Schemes\Apps\devenv8\VS_BuildFailed\.current", "", "").ToString()



    '-------------------------------------------------------
    ' ブレークポイント用変数の痕跡
    ' -> 要らない子になりました…
    '-------------------------------------------------------
    Private ReadOnly strFileNameBreakPoint As String = ""
    'Private ReadOnly strFileNameBreakPoint As String = My.Computer.Registry.GetValue("HKEY_CURRENT_USER\AppEvents\Schemes\Apps\devenv\VS_BreakpointHit_vs2005\.current", "", "").ToString()
    'Private ReadOnly strFileNameBreakPoint As String = My.Computer.Registry.GetValue("HKEY_CURRENT_USER\AppEvents\Schemes\Apps\devenv8\VS_BreakpointHit\.current", "", "").ToString()


    '-------------------------------------------------------
    ' 日本語環境外の時は下の変数を編集する事
    ' If your platform is *not* Japanese, change lower variables.
    '-------------------------------------------------------
    Const WARNING_STRING As String = "警告"
    Const ERROR_STRING As String = "エラー"
    Const SPLIT_STRING As String = "、"



    ' 再生する種類
    Enum SoundType
        ST_SUCCEEDED
        ST_WARNING
        ST_FAILED
        ST_BREAK_POINT
        ST_NONE

        ST_MAX
    End Enum

    ' ファイル一覧
    Dim astrFileList() As String = _
    { _
        strFileNameSucceeded, _
        strFileNameWarning, _
        strFileNameFailed, _
        strFileNameBreakPoint, _
        "" _
    }


    ' sndPlaySoundA を利用します。
    Declare Function sndPlaySound Lib "winmm.dll" Alias "sndPlaySoundA" _
        (ByVal lpszSoundName As String, ByVal uFlags As Long) As Long

    ' 音鳴らします
    Private Sub PlaySound(ByVal type As SoundType)
        sndPlaySound(astrFileList(type), 3)
    End Sub



    '---------------------------------------------------------------------------------
    ' break point
    ' -> なんでか VS2003 のブレークポイントの設定をを見に行ってくれるので実質不要。
    '    …バグやでこれ?(ビルド完了・ビルド失敗 の音が鳴らない事が)
    '---------------------------------------------------------------------------------
    'Public Sub DebuggerEvents_OnEnterBreakModeEventHandler(ByVal Reason As dbgEventReason, ByRef ExecutionAction As dbgExecutionAction) Handles DebuggerEvents.OnEnterBreakMode
    '    PlaySound(SoundType.ST_BREAK_POINT)
    'End Sub


    '---------------------------------------------------------------------------------
    ' build event
    '---------------------------------------------------------------------------------

    ' "エラー 0、警告 0" みたいな文字列を解析します。
    Private Function ComputeSoundType(ByVal matches As MatchCollection) As SoundType
        ' scanf が欲しい… orz
        Dim total_err As Long = 0
        Dim total_warn As Long = 0

        For Each line As Match In matches
            Dim str() As String = line.Value.Split(SPLIT_STRING)

            ' 保険 ^^;
            If str.Length = 2 Then
                total_err += Integer.Parse(Regex.Match(str(0), "\d+").Value)
                total_warn += Integer.Parse(Regex.Match(str(1), "\d+").Value)
            End If
        Next

        ' ここで PlaySoundしても、結果は同じだけど…管轄外にするのが良いと思うんだよね。
        If matches.Count = 0 Then   ' ここはありえないハズだけどねー
            ComputeSoundType = SoundType.ST_NONE
        ElseIf total_err <> 0 Then
            ComputeSoundType = SoundType.ST_FAILED
        ElseIf total_warn <> 0 Then
            ComputeSoundType = SoundType.ST_WARNING
        Else
            ComputeSoundType = SoundType.ST_SUCCEEDED
        End If

    End Function

    ' イベント本体
    ' ビルドイベント完了後(正確には完了直前)に1回だけ呼ばれる
    Public Sub _dispBuildEvents_OnBuildDoneEventHandler(ByVal Scope As vsBuildScope, ByVal Action As vsBuildAction) Handles BuildEvents.OnBuildDone
        Dim pPane As OutputWindow = DTE.Windows.Item(Constants.vsWindowKindOutput).Object
        Dim pSele As TextSelection = pPane.ActivePane.TextDocument.Selection

        ' アウトプットウィンドウの文字列を取得するにょ
        pSele.SelectAll()
        Dim strOut As String = pSele.Text
        pSele.EndOfDocument()

        ' "エラー \d+、警告 \d+" を検索
        Dim strFindRegex As String = ERROR_STRING & " \d+" & SPLIT_STRING & WARNING_STRING & " \d+"
        Dim eSoundType As SoundType = ComputeSoundType(Regex.Matches(strOut, strFindRegex))

        ' 結果を元に音再生
        PlaySound(eSoundType)
    End Sub

誰か最適なコード書いてくだちぃ…^^;