windows jenkens延时ping -n 11 127.0.0.1 >nul
使用timeout /t 10 /nobreak 报错“错误: 不支持输入重新定向,立即退出此进程。”
在 Windows 上,Jenkins 报 “Process leaked file descriptors” 说明你的 MFC 程序可能有 未正确关闭的文件句柄。要找出具体 哪个文件句柄泄露了,可以使用以下方法分析:
handle.exe
检查进程文件句柄Windows 没有 lsof
,但可以用 Sysinternals Handle 工具检查哪些文件句柄未关闭。
handle.exe
handle.exe
,放到 C:\Windows\System32\
(或者你的 PATH
路径)先让 MFC 程序运行,在 Jenkins 执行 exit(0)
之前 运行:
handle.exe -p your_mfc_program.exe > before_exit.log
然后在 程序退出后 再执行:
handle.exe -p your_mfc_program.exe > after_exit.log
然后对比 before_exit.log
和 after_exit.log
,找出哪些文件句柄 没有正确释放。
Process Explorer
查看句柄如果 handle.exe
输出太多,可以用 GUI 版的 Process Explorer
:
procexp.exe
procexp.exe
_CrtDumpMemoryLeaks()
检查 MFC 资源泄露如果你的程序在 exit(0)
退出时仍然 持有 GDI 资源、文件句柄、内存分配,可以在 ExitInstance()
里添加:
#ifdef _DEBUG
_CrtDumpMemoryLeaks();
#endif
然后在 Debug 控制台 查看输出,找出 未释放的对象。
你可以使用 NtQuerySystemInformation()
或 EnumProcessModules()
手动遍历当前进程的所有打开句柄:
#include
#include
#include
void PrintOpenHandles()
{
HANDLE hProcess = GetCurrentProcess();
DWORD handleCount = 0;
if (GetProcessHandleCount(hProcess, &handleCount))
{
printf("Process has %lu open handles\n", handleCount);
}
}
在程序退出前调用:
PrintOpenHandles();
exit(0);
如果 handleCount
始终不为 0,说明有资源未释放。
如果你的代码使用了 CreateFile()
或 fopen()
,确保调用了 CloseHandle()
或 fclose()
:
HANDLE hFile = CreateFile(L"log.txt", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile != INVALID_HANDLE_VALUE) {
// 正确释放文件句柄
CloseHandle(hFile);
}
如果你使用了 socket()
或 WSAStartup()
,确保在退出前 调用 closesocket()
:
closesocket(my_socket);
WSACleanup();
如果你用 CreateDC()
、CreateFont()
,确保调用:
DeleteDC(hDC);
DeleteObject(hFont);
Resource Monitor
查看文件锁Windows 自带 资源监视器(Resource Monitor),可以查找进程 锁住的文件:
Win + R
,输入 resmon.exe
打开资源监视器方法 | 作用 |
---|---|
handle.exe -p |
列出所有文件句柄,找到未关闭的文件 |
Process Explorer (procexp.exe ) |
GUI 方式查看未释放的资源 |
_CrtDumpMemoryLeaks() |
在 Debug 模式下检查 MFC 资源泄露 |
PrintOpenHandles() |
手动打印程序的打开句柄数量 |
resmon.exe (资源监视器) |
查找进程锁住的文件 |
handle.exe -p your_mfc_program.exe > before_exit.log
exit(0)
handle.exe -p your_mfc_program.exe > after_exit.log
before_exit.log
和 after_exit.log
,找到泄露的句柄ExitInstance()
释放所有资源Process leaked file descriptors
这样,你就能精准找到 泄露的句柄 并修复它!