Я использую стороннюю библиотеку, которая использует функцию OutputDebugString()
, и при чтении документации MSDN, кажется, указывает, что это для печати в отладчике.
Но это неудобно в моем случае, есть ли способ прочитать этот вывод, если не подключен отладчик?
Если бы это была моя LIB, я бы предпочел, чтобы выходные данные переходили в stdout / stderr всякий раз, когда пользователь проходит --debug
или аналогичные, но так как это не так, я ищу другие способы передачи этой информации в консоль (или файл) без подключения отладчика.
OutputDebugStringA
генерировать исключение DBG_PRINTEXCEPTION_C
(W
версия в win10 — DBG_PRINTEXCEPTION_WIDE_C
) с 2 аргументами — (длина строки в символах + 1, указатель строки) — в результате мы можем обработать это исключение самостоятельно (системный обработчик по умолчанию для этого исключения делает этот).
пример обработчика для перенаправления OutputDebugString
утешить:
LONG NTAPI VexHandler(PEXCEPTION_POINTERS ExceptionInfo)
{
PEXCEPTION_RECORD ExceptionRecord = ExceptionInfo->ExceptionRecord;
switch (ExceptionRecord->ExceptionCode)
{
case DBG_PRINTEXCEPTION_WIDE_C:
case DBG_PRINTEXCEPTION_C:
if (ExceptionRecord->NumberParameters >= 2)
{
ULONG len = (ULONG)ExceptionRecord->ExceptionInformation[0];
union {
ULONG_PTR up;
PCWSTR pwz;
PCSTR psz;
};
up = ExceptionRecord->ExceptionInformation[1];
HANDLE hOut = GetStdHandle(STD_ERROR_HANDLE);
if (ExceptionRecord->ExceptionCode == DBG_PRINTEXCEPTION_C)
{
// localized text will be incorrect displayed, if used not CP_OEMCP encoding
// WriteConsoleA(hOut, psz, len, &len, 0);
// assume CP_ACP encoding
if (ULONG n = MultiByteToWideChar(CP_ACP, 0, psz, len, 0, 0))
{
PWSTR wz = (PWSTR)alloca(n * sizeof(WCHAR));
if (len = MultiByteToWideChar(CP_ACP, 0, psz, len, wz, n))
{
pwz = wz;
}
}
}
if (len)
{
WriteConsoleW(hOut, pwz, len - 1, &len, 0);
}
}
return EXCEPTION_CONTINUE_EXECUTION;
}
return EXCEPTION_CONTINUE_SEARCH;
}
а для установки этого обработчика нужно вызвать:
AddVectoredExceptionHandler(TRUE, VexHandler);
внедрение системы OutputDebugString
лайк Вот — это действительно называется RaiseException
именно с этими аргументами, только в обработчике исключений вместо MessageBox
— код описан Вот.
Других решений пока нет …