VB.NETからOBSへキーを送信しホットキーを操作するサンプルコード

VB.NET(Visual Basic.NET)からOBSに、1文字を送るサンプルコードです。
OBS画面右下にある設定内のホットキー項目で、ホットキーを設定し、VB.NETのプログラム上からOBSのホットキーを押したかったので作りました。

ただし、ホットキーに「Ctrl」や「Shift」、「Alt」があると、どうしてもダメでしたので、単一キーでの利用に制限されています。

例えば、OBSのホットキーの設定で、Fキーを押したら、音楽が再生される設定をしたとします。
それをOBSでキーボードからFを押して、再生させるのではなく、VB.NETで作ったEXEから押したいような時に使えます。
(VB.NETでコード書いて、音楽再生さればいいじゃん!ってのもありますが、まあ他のアプリにキーを送信してみたかったので)

使用例としては、特定の時間を迎えたら、放送中に放送主が意識せずに音楽を流すなんてことができるようになります。
放送者が意識せずに、特定の条件になった時に、勝手にホットキーを押してもらいたい時に使えると思います。

【2024年3月17日に追記】OBS30.1で使用できなくなった

ここで紹介しているソースコードはOBS30.1で使用できなくなりました。
OBS30.0.2までであれば利用可能となります。

プログラムの内容

やっていることは、OBSのウィンドウタイトル、クラス名を取得し、その情報からOBSのハンドルを取得し、ハンドルを使ってSendMessageでキーを1文字送信しています。

OBSのホットキーは「Ctrl」「Shift」「Alt」を使用せずに、キーを設定します。
この記事では、OBSのホットキーの使い方については、割愛します。

サンプルコードの使用方法

1.VB.NETを起動し「新規プロジェクトの作成(N)」「Windowsフォームアプリ」を選択します。

2.まっさらのForm1にButton1とListBox1を設置します。

3.コードエディタに、下記のコードをまるごと貼り付ければOKです。

4.OBSは予め起動し、ホットキーの設定でFを押されたら何かが起こるように設定しておいてください。

5.プログラムを実行して、ボタンを押すと、FキーがOBSに送信されます。

もちろんソースコードを改良すれば、違うキーを送信することが可能です。
参照設定も、何も設定の必要がありません。

ソースコード


Imports System.Runtime.InteropServices Imports System.Text Public Class Form1 Private Declare Function FindWindow Lib "user32.dll" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Integer Private Declare Function SendMessage Lib "user32.dll" Alias "SendMessageA" (ByVal hWnd As Integer, ByVal Msg As Integer, ByVal wParam As Integer, ByVal lParam As Integer) As Integer Private Delegate Function EnumWindowsDelegate(hWnd As IntPtr, lparam As IntPtr) As Boolean Private Shared Function EnumWindows(lpEnumFunc As EnumWindowsDelegate, lparam As IntPtr) As Boolean End Function Private Shared Function GetWindowText(hWnd As IntPtr, lpString As StringBuilder, nMaxCount As Integer) As Integer End Function Private Shared Function GetWindowTextLength(hWnd As IntPtr) As Integer End Function Private Shared Function GetClassName(hWnd As IntPtr, lpClassName As StringBuilder, nMaxCount As Integer) As Integer End Function Private Const cOBS_Left3 As String = "OBS" 'OBSのウィンドウタイトルの最初の3文字(OBSを起動し、左上を見て目視で確認) Private Const cWindowsMessage_Char_Send As Integer = &H286S '文字コードを送信するという命令コード(固定値) Private Function Get_Obs_Handle(hWnd As IntPtr, lparam As IntPtr) As Boolean Dim wOBS_WindowTitle As String 'OBSのウィンドウタイトル Dim wOBS_ClassName As String 'OBSのクラス名 Dim wOBS_hand As Integer 'OBSのハンドル Dim wRet As Integer '================================================================= 'ウィンドウのタイトルの長さを取得する '================================================================= Dim wLen As Integer = GetWindowTextLength(hWnd) '================================================================= 'ウィンドウタイトルが""のハンドルやクラス名取得しても意味ないので '================================================================= If wLen > 0 Then '================================================================= 'ウィンドウのタイトルを取得する '================================================================= Dim wWindowTitle As New StringBuilder(wLen + 1) GetWindowText(hWnd, wWindowTitle, wWindowTitle.Capacity) '================================================================= 'ウィンドウのクラス名を取得する '================================================================= Dim wWindowClassName As New StringBuilder(256) GetClassName(hWnd, wWindowClassName, wWindowClassName.Capacity) '================================================================= '結果をリスト表示する '================================================================= Listbox1.Items.Add("クラス名:" & wWindowClassName.ToString()) Listbox1.Items.Add("タイトル:" & wWindowTitle.ToString()) '================================================================= 'Windowsタイトルの最初の3文字がOBSだったら '================================================================= If Strings.Left(wWindowTitle.ToString(), 3) = cOBS_Left3 Then '============================================================= '今調査しているのはあくまでOBSだったので、ほしいものを取得 '============================================================= wOBS_WindowTitle = wWindowTitle.ToString() 'ウィンドウタイトル取得 wOBS_ClassName = wWindowClassName.ToString() 'クラス名取得 '============================================================= 'ウィンドウタイトルとクラス名とAPIのちからを使ってハンドルゲット '============================================================= wOBS_hand = FindWindow(wOBS_ClassName, wOBS_WindowTitle) 'ハンドル取得 '============================================================================ 'キーコードに変換し、SendメッセージでOBSのハンドルを指定してキーを送る ' '別のキーについて(第3引数について) '例えばファンクションF5にしたい場合、F5は116(&H74)なので、その数値を送れば良い 'テンキーの1の場合は、97(&H61)なので、その数値を送れば良い 'BackSpaceなら8、Homeキーなら36、←キーなら37など '============================================================================ wRet = SendMessage(wOBS_hand, cWindowsMessage_Char_Send, Asc("F"), 0) '無事にFキーを送信しました。お疲れ様でした。 End If End If Get_Obs_Handle = True End Function Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click '============================================================================ 'OBSが起動している状態でボタンを押す。 'なおかつOBSのホットキーで、Fキーが押されたら、 'なにか明確に分かるような設定をOBSにしておく。 'OBSが起動していない場合は何も起こりません。 ' 'この行↓をプロセス全部列挙するまで、何回も繰り返しているイメージ(Do Untilと同様のイメージ) '============================================================================ EnumWindows(New EnumWindowsDelegate(AddressOf Get_Obs_Handle), IntPtr.Zero) End Sub End Class

注意点

ソースコードは、自由にコピー、改変してもらって問題ありません。
ただし、問題があっても責任を負わないものとします。
また、コードはVB.NETであり、昔なつかしのVisualBasic6.0ではないのでご注意ください。

1つだけ使用上の注意があります

受け側のOBSのウィンドウ内で、カレントオブジェクトが配信画面を映すメイン画面である必要があります。
具体的には、配信画面が映っているところをマウスで1回クリックするだけでOKです。
これが、OBS内でソースだったり、シーンだったり、ミキサーを利用して、OBS内のボタンやメニューを押してしまい、カレントオブジェクトがそれらになっているとVB.NETからキーを送信してもOBS側が反応しません。
OBS側でマウスを使って何かを操作したら、最後に配信画面を映すメイン画面をマウスでクリックすれば確実に動作します。

不安点

今後、OBSがアップデートしたら使えなくなってしまうかもしれません。
将来がどうなるかは分かりません。

使用言語・動作確認したバージョン

OBS 29.0.0(64-bit,windows)
Microsoft Visual Studio Community 2022 (64 ビット)


関連記事

A.I.VOICEが喋っているか喋っていないかをVB.NETで判断するソースコード
VB.NETでA.I.VOICEに喋らせる為の最短の設定とサンプルソースコード
VB.NETで棒読みちゃんに文字を読ませるサンプルコード
タイトルとURLをコピーしました