如何解决在Windows10中,EnumICMProfiles API泄漏句柄
Windows API EnumICMProfiles枚举与给定DC的显示设备关联的ICC配置文件。可能有特定显示器的自定义配置文件,只有sRGB,或者两者都有。在Windows 10中的某个时候,此API开始泄漏句柄。在我测试的多台计算机上,每个呼叫都会泄漏8个句柄。除非应用程序多次调用它并且在许多天内被广泛使用,否则这不是主要问题。最终,泄漏可能导致其他句柄分配出现问题。
在Windows 7,Windows 8.1或Windows 10内部版本1607中不存在该问题。有关详细信息,请参阅代码注释。这似乎是Windows API源中的注册表句柄泄漏,因此可能未调用某些RegCloseKey。
#include <windows.h>
#include <stdio.h>
#include <tchar.h>
#pragma comment(lib,"user32.lib")
#pragma comment(lib,"gdi32.lib")
int CALLBACK TestEnumProfilesFunc(LPTSTR lpszFilename,LPARAM lParam)
{
if (lpszFilename && *lpszFilename && lParam)
{
unsigned *pCount = (unsigned *)lParam;
(*pCount)++;
}
return TRUE; // TRUE==keep enumerating. Even if we enumerate one profile and return FALSE,it still leaks same # of handles
}
int main(void)
{
TCHAR szMsg[256];
HANDLE hProcess = GetCurrentProcess();
HDC hScreenDC = ::GetDC(NULL); // Get screen DC and release it before establishing baseline handle count
if (hScreenDC != 0)
::ReleaseDC(NULL,hScreenDC);
DWORD nOrigHandles = 0;
GetProcessHandleCount(hProcess,&nOrigHandles);
DWORD LastHandleCount = nOrigHandles;
int nIterations = 100;
for (int i = 0; i < nIterations; i++)
{
hScreenDC = ::GetDC(NULL);
if (hScreenDC == 0)
break;
unsigned nProfiles = 0;
EnumICMProfiles(hScreenDC,TestEnumProfilesFunc,(LPARAM)&nProfiles);
// Also,both EnumICMProfilesA and EnumICMProfilesW leak the same
// Return value is -1,1 result code so there's nothing the caller can close
::ReleaseDC(NULL,hScreenDC);
// First call will leave many handles open,those may be okay as they may be cached and released later
// Subsequent calls leak 8 handles per two enumerated profiles
// No leaked handles if we don't call EnumICMProfiles
// No leak in Windows 7 or Windows 8.1
// No leak in Windows 10 1607
// leaks in Windows 10 1809 build 17763.379
// leaks in Windows 10 1903 and 1909
// Leaks 2 handles if no ICM profiles associated with display device
// Leaks 8 handles if 1 or more ICM profiles set for display device
// Using Windows SysInternals ProcessExplorer or similar to view handles,the leaked handles appear to be
// registry handles to the display driver associated with the DC. The leak might be missing RegCloseKey's.
DWORD nHandles = 0;
GetProcessHandleCount(hProcess,&nHandles);
wsprintf(szMsg,_T("%8u Iterations\n"
"%8u Total Current Handles Orig=%u\n"
"%8u Leaked Handles\n"
"%8u Profiles on DC\n"
),i + 1,nHandles,nOrigHandles,nHandles > LastHandleCount ? nHandles-LastHandleCount : 0,nProfiles);
if (MessageBox(NULL,szMsg,_T("EnumICMProfiles"),MB_ICONINFORMATION | MB_OKCANCEL)==IDCANCEL)
break;
LastHandleCount = nHandles;
}
// The handles will go away when the process terminates,but the problem is an application that regularly calls this may build up many leaked handles.
// Other handle allocation may fail once the # of leaked handles gets too high.
return 0;
}
解决方法是不经常调用它。在此处b / c发布Microsoft没有容易,免费的位置来报告错误。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。