自定义控制台环境初始化NDI时触发netsh.exe 0xc0000142错误咨询
问题原因
NDI 库执行initialize()方法时,会在内部拉起netsh.exe子进程完成网卡枚举、防火墙规则配置等网络侧初始化操作。
你的控制台操作逻辑存在两个缺陷,直接导致子进程启动失败抛出0xc0000142错误:
- 调用
FreeConsole()释放进程原有控制台关联后,没有清理旧的标准句柄(STDIN/STDOUT/STDERR)引用,这些句柄已经处于无效状态 - 调用
AllocConsole()创建新控制台、替换活动屏幕缓冲区后,没有将新控制台的IO句柄重新绑定到进程的标准句柄表中
netsh.exe是控制台类型子进程,启动时会默认继承父进程的标准控制台句柄,此时拿到的是已经失效的旧句柄,直接在进程初始化阶段触发崩溃。之所以跳过错误后NDI功能完全正常,是因为NDI核心音视频传输逻辑不依赖这步netsh调用的返回结果,子进程崩溃不会阻断主库的加载运行。这个报错和系统中netsh程序损坏、缺失没有关系,不需要修复系统文件。
修复方法
两种方案选其一即可解决问题:
- 方案1:把自定义控制台的初始化逻辑(
FreeConsole/AllocConsole/自定义屏幕缓冲区)整体移动到m_NDILib->initialize()执行完成之后再调用,彻底避免NDI拉起子进程时碰到无效控制台句柄,这个方案改动量最小。 - 方案2:如果必须在NDI初始化前完成自定义控制台配置,在
AllocConsole()调用后立刻补全标准句柄的重绑定逻辑,再执行后续操作。修复后的最小示例代码如下:
#include <iostream> #include <Windows.h> #include "ndi/Processing.NDI.Lib.h" int main() { FreeConsole(); AllocConsole(); // 重绑定C运行层的标准io到新控制台 FILE* fp; freopen_s(&fp, "CONIN$", "r", stdin); freopen_s(&fp, "CONOUT$", "w", stdout); freopen_s(&fp, "CONOUT$", "w", stderr); // 创建自定义屏幕缓冲区并设为活动状态 HANDLE hNewBuffer = CreateConsoleScreenBuffer(GENERIC_WRITE | GENERIC_READ, 0, NULL, CONSOLE_TEXTMODE_BUFFER, NULL); SetConsoleActiveScreenBuffer(hNewBuffer); // 把新屏幕缓冲区绑定到内核层标准输出、错误句柄,保证子进程能继承到合法句柄 SetStdHandle(STD_OUTPUT_HANDLE, hNewBuffer); SetStdHandle(STD_ERROR_HANDLE, hNewBuffer); HMODULE m_NDIHandler = LoadLibraryA("Processing.NDI.Lib.x64.dll"); const NDIlib_v5* (*NDIlib_v5_load)(void) = NULL; if (m_NDIHandler) { *((FARPROC*)&NDIlib_v5_load) = GetProcAddress(m_NDIHandler, "NDIlib_v5_load"); } const NDIlib_v5* m_NDILib = NDIlib_v5_load(); // 此时执行初始化不会再弹出netsh报错 m_NDILib->initialize(); return 0; }
补充说明:后续如果需要调用
WriteConsole实现控制台输出,直接使用绑定完成的标准输出句柄即可,不需要额外调整句柄权限。
内容的提问来源于stack exchange,提问作者user2123079
相关产品推荐
相关产品推荐

