OutputDebugStringを自前で受け取るプログラムを作りたくなったのでメモ
#環境
- Windows 10
- Visual Studio 2019 C++
本文
1. 以下を参考に前半部分を作成
link:OutputDebugStringで出力したデバッグライトを自前で受け取る
変更点
- (HANDLE)(-1)にした
hMapFile = CreateFileMapping((HANDLE)(-1), &sa, PAGE_READWRITE, 0, 4096, TEXT("DBWIN_BUFFER"));
2. 1.コードだけでは一時期うまくいかなかった気がしたが、
最終的に取得できるようになった
以下資料があるが、最終的には変更しなかった
⇒ Global はつけない
⇒ つけると、起動の際に管理者権限要求されて面倒
link:How can I receive OutputDebugString from a service?
3. 後半部分はウィンドウプロシージャ用に変更
- 受信文字列用にLPSTRと適当に変更
- WaitForSingleObject を MsgWaitForMultipleObjects に変更
- 末尾にUnmapViewOfFileとCloseHandle 追加
- メッセージポンプの追加
- メッセージポンプにWM_QUITの追加
⇒メッセージポンプの追加だけだと、MsgWaitForMultipleObjects待機中に終了した際、プロセスに残ってしまう
以下により、とりあえずWM_QUIT受信時に、関数終了させてPostQuitMessageを再送させた
link:作業から なかなか帰れないプログラム
//--------------- 先頭DWORDがプロセスID、以下が格納文字列
LPDWORD pPID = (LPDWORD)pMem;
LPSTR pString = (LPSTR)pPID + sizeof(DWORD);
SetEvent(hEvAck);
while (bGetStringDo) //別に定義される static bool bGetStringDo; // TRUEで取り込み中
{
DWORD dstat = MsgWaitForMultipleObjects(1, &hEvReady, 0, INFINITE, QS_ALLINPUT) ;
switch (dstat)
{
case WAIT_OBJECT_0:
{
//------------ ここで受け取った文字列、pStringをコンソールなりファイルなりに出力すればよい
//------------
SetEvent(hEvAck);
break;
}
case WAIT_FAILED:
{
bGetStringDo = false;
break;
}
default:
{
break;
}
}
MSG msg;
if (::PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
if (msg.message == WM_QUIT)
{
bGetStringDo = false;
PostQuitMessage(0);
}
else
{
::TranslateMessage(&msg);
::DispatchMessage(&msg);
}
}
}
UnmapViewOfFile(pMem);
CloseHandle(hMapFile);
CloseHandle(hEvReady);
CloseHandle(hEvAck);
return 0; // int WaitOutputDebugString()