应用程序启动时奇怪的 comctl32.dll 加载/卸载

Posted

技术标签:

【中文标题】应用程序启动时奇怪的 comctl32.dll 加载/卸载【英文标题】:Weird loading/unloading of a comctl32.dll on app startup 【发布时间】:2012-02-23 12:59:43 【问题描述】:

在程序启动时,在调试器跟踪中,我可以看到:

'VideoPhillPlayer.exe': Loaded 'C:\Windows\winsxs\x86_microsoft.windows.common-controls_6595b64144ccf1df_5.82.7600.16661_none_ebfb56996c72aefc\comctl32.dll'
'VideoPhillPlayer.exe': Unloaded 'C:\Windows\winsxs\x86_microsoft.windows.common-controls_6595b64144ccf1df_5.82.7600.16661_none_ebfb56996c72aefc\comctl32.dll'
'VideoPhillPlayer.exe': Loaded 'C:\Windows\winsxs\x86_microsoft.windows.common-controls_6595b64144ccf1df_5.82.7600.16661_none_ebfb56996c72aefc\comctl32.dll'
'VideoPhillPlayer.exe': Unloaded 'C:\Windows\winsxs\x86_microsoft.windows.common-controls_6595b64144ccf1df_5.82.7600.16661_none_ebfb56996c72aefc\comctl32.dll'
'VideoPhillPlayer.exe': Loaded 'C:\Windows\winsxs\x86_microsoft.windows.common-controls_6595b64144ccf1df_5.82.7600.16661_none_ebfb56996c72aefc\comctl32.dll'
'VideoPhillPlayer.exe': Unloaded 'C:\Windows\winsxs\x86_microsoft.windows.common-controls_6595b64144ccf1df_5.82.7600.16661_none_ebfb56996c72aefc\comctl32.dll'
'VideoPhillPlayer.exe': Loaded 'C:\Windows\winsxs\x86_microsoft.windows.common-controls_6595b64144ccf1df_5.82.7600.16661_none_ebfb56996c72aefc\comctl32.dll'
'VideoPhillPlayer.exe': Unloaded 'C:\Windows\winsxs\x86_microsoft.windows.common-controls_6595b64144ccf1df_5.82.7600.16661_none_ebfb56996c72aefc\comctl32.dll'

这只是一个sn-p。它一次持续 100 行...

谁能解释一下原因???

编辑:

我在 x64 Windows 下运行 x86 代码,并且在跟踪窗口中也得到了这个:

'VideoPhillPlayer.exe': Loaded 'ImageAtBase0x504b0000', No symbols loaded.
'VideoPhillPlayer.exe': Loaded 'ImageAtBase0x5720000', No symbols loaded.
'VideoPhillPlayer.exe': Unloaded 'ImageAtBase0x504b0000'

'VideoPhillPlayer.exe': Loaded 'ImageAtBase0x54610000', No symbols loaded.
'VideoPhillPlayer.exe': Loaded 'ImageAtBase0x65c0000', No symbols loaded.
'VideoPhillPlayer.exe': Unloaded 'ImageAtBase0x54610000'

【问题讨论】:

从立即的投票来看,似乎不是只有我一个人有问题? 我记得前段时间看过,因为太忙而忽略了。这就是我感兴趣的原因。根据调查问题的可能方法,ProcessMonitor 和 Fusion logging 工具可能会为您提供帮助。 使用进程监视器,您可以检查哪些进程正在访问 comctl32.dll,而使用 Fusion 日志,您可以检查 CLR 在哪些位置寻找该 dll。尽管后者可能没有太大帮助,因为它似乎总是在同一个位置找到它。如果您的 .exe 有任何挥之不去的实例正在运行,请检查任务管理器 右键单击输出窗口并取消选中“模块加载消息”。让您不必担心不是您编写并且可能无法更改的代码。 @HansPassant 这似乎是合理的,但是由于疯狂的加载/卸载,应用程序加载时间增加了......顺便说一句,有时把头放在沙子里似乎是完美的选择,但我真的很好奇关于这个。 【参考方案1】:

这个article 有一些关于 ComCtl32.dll 的一般信息。长话短说,这没什么好担心的。它是一个包含 Windows UI 组件的 DLL,因此被 Windows 应用程序广泛使用:ComCtl 是通用控件的缩写。您会看到它正在加载和卸载,因为您的应用程序中的各种窗口和其他控件都在使用它的功能。

想要更全面的答案的可以跑

dumpbin /exports C:\Windows\System32\ComCtl32.dll

获得大量由 DLL 导出的函数。对于那些既好奇又懒惰的人来说,这里是 - 你可以看到它只包含 Windows 控件的各种实用功能:

Dump of file C:\Windows\System32\comctl32.dll

File Type: DLL

  Section contains the following exports for COMCTL32.dll

    00000000 characteristics
    4CE779FD time date stamp Sat Nov 20 02:34:21 2010
        0.00 version
           2 ordinal base
         420 number of functions
         119 number of names

    ordinal hint RVA      name

        401    0 0000912C AddMRUStringW
        400    1 00008F94 CreateMRUListW
          8    2 00009F9C CreateMappedBitmap
         12    3 0000CD80 CreatePropertySheetPage
         18    4 0000CD80 CreatePropertySheetPageA
         19    5 0000CD70 CreatePropertySheetPageW
         20    6 00014AC8 CreateStatusWindow
          6    7 00014AC8 CreateStatusWindowA
         21    8 00014A64 CreateStatusWindowW
          7    9 00016190 CreateToolbar
         22    A 00016028 CreateToolbarEx
         16    B 0001FC64 CreateUpDownControl
        331    C 00020C54 DPA_Clone
        328    D 00020B98 DPA_Create
        340    E 00020BA8 DPA_CreateEx
        337    F 00020FCC DPA_DeleteAllPtrs
        336   10 00020F0C DPA_DeletePtr
        329   11 00020C0C DPA_Destroy
        386   12 00021080 DPA_DestroyCallback
        385   13 00021014 DPA_EnumCallback
        332   14 00020CDC DPA_GetPtr
        333   15 00020D00 DPA_GetPtrIndex
        330   16 00020D40 DPA_Grow
        334   17 00020E80 DPA_InsertPtr
          9   18 00021258 DPA_LoadStream
         11   19 00021408 DPA_Merge
         10   1A 000210A4 DPA_SaveStream
        339   1B 00021810 DPA_Search
        335   1C 00020DFC DPA_SetPtr
        338   1D 000215D8 DPA_Sort
        320   1E 00020790 DSA_Create
        327   1F 00020B58 DSA_DeleteAllItems
        326   20 00020AB4 DSA_DeleteItem
        321   21 000207D8 DSA_Destroy
        388   22 00020898 DSA_DestroyCallback
        387   23 0002082C DSA_EnumCallback
        322   24 000208BC DSA_GetItem
        323   25 000208F8 DSA_GetItemPtr
        324   26 000209E8 DSA_InsertItem
        325   27 00020914 DSA_SetItem
        413   28 00022318 DefSubclassProc
         23   29 0000C378 DestroyPropertySheetPage
         24   2A 0007E480 DllGetVersion
         15   2B 000230F8 DrawInsert
         25   2C 00012EFC DrawStatusText
          5   2D 00012EFC DrawStatusTextA
         26   2E 00012ED0 DrawStatusTextW
        403   2F 000099B0 EnumMRUListW
         27   30 00025980 FlatSB_EnableScrollBar
         28   31 000255BC FlatSB_GetScrollInfo
         29   32 000252C8 FlatSB_GetScrollPos
         30   33 000254D8 FlatSB_GetScrollProp
         31   34 0002533C FlatSB_GetScrollPropPtr
         32   35 00025508 FlatSB_GetScrollRange
         33   36 000268C4 FlatSB_SetScrollInfo
         34   37 000266F0 FlatSB_SetScrollPos
         35   38 000269D0 FlatSB_SetScrollProp
         36   39 00026790 FlatSB_SetScrollRange
         37   3A 000256CC FlatSB_ShowScrollBar
        152   3B 0000906C FreeMRUList
          4   3C 000270D8 GetEffectiveClientRect
         38   3D 00027650 GetMUILanguage
         39   3E 000784B0 ImageList_Add
         40   3F 00078158 ImageList_AddIcon
         41   40 000786E8 ImageList_AddMasked
         42   41 00077C6C ImageList_BeginDrag
         43   42 00078A2C ImageList_Copy
         44   43 00077EB8 ImageList_Create
         45   44 000783C4 ImageList_Destroy
         46   45 00077CE0 ImageList_DragEnter
         47   46 00077D58 ImageList_DragLeave
         48   47 00077D20 ImageList_DragMove
         49   48 00077D8C ImageList_DragShowNolock
         50   49 00078840 ImageList_Draw
         51   4A 00078748 ImageList_DrawEx
         52   4B 00078914 ImageList_DrawIndirect
         53   4C 0007820C ImageList_Duplicate
         54   4D 00077C18 ImageList_EndDrag
         55   4E 000785C4 ImageList_GetBkColor
         56   4F 00077BD0 ImageList_GetDragImage
         57   50 00078D60 ImageList_GetFlags
         58   51 000789CC ImageList_GetIcon
         59   52 00078AA0 ImageList_GetIconSize
         60   53 0007840C ImageList_GetImageCount
         61   54 00078B74 ImageList_GetImageInfo
         62   55 0007835C ImageList_GetImageRect
         63   56 00077F74 ImageList_LoadImage
         64   57 00077F74 ImageList_LoadImageA
         65   58 00078020 ImageList_LoadImageW
         66   59 00078BD8 ImageList_Merge
         67   5A 000782C8 ImageList_Read
         68   5B 00078978 ImageList_Remove
         69   5C 00078674 ImageList_Replace
         70   5D 00078510 ImageList_ReplaceIcon
         75   5E 00078570 ImageList_SetBkColor
         76   5F 00077B4C ImageList_SetDragCursorImage
         77   60 00079FF8 ImageList_SetFilter
         78   61 00078C98 ImageList_SetFlags
         79   62 00078B0C ImageList_SetIconSize
         80   63 00078458 ImageList_SetImageCount
         81   64 00078610 ImageList_SetOverlayImage
         82   65 00078260 ImageList_Write
         17   66 0002751C InitCommonControls
         83   67 00027528 InitCommonControlsEx
         84   68 00027618 InitMUILanguage
         85   69 000233F4 InitializeFlatSB
         14   6A 00022FA0 LBItemFromPt
         13   6B 00022F0C MakeDragList
          2   6C 00026DA8 MenuHelp
         86   6D 00012820 PropertySheet
         87   6E 00012820 PropertySheetA
         88   6F 00012810 PropertySheetW
         89   70 00027660 RegisterClassNameW
        412   71 00022244 RemoveWindowSubclass
        410   72 00022138 SetWindowSubclass
          3   73 00026FD0 ShowHideMenuCtl
        236   74 00021B38 Str_SetPtrW
         90   75 00023260 UninitializeFlatSB
         91   76 0002BF50 _TrackMouseEvent
         71      00009BF0 [NONAME]
         72      00009C08 [NONAME]
         73      00009C38 [NONAME]
         74      00009C58 [NONAME]
        151      00009058 [NONAME]
        153      000093B0 [NONAME]
        154      00009A74 [NONAME]
        155      00009948 [NONAME]
        156      000093FC [NONAME]
        157      00008FA8 [NONAME]
        163      0000CABC [NONAME]
        164      00012610 [NONAME]
        167      000094E8 [NONAME]
        169      0000971C [NONAME]
        233      000219BC [NONAME]
        234      00021BBC [NONAME]
        235      00021918 [NONAME]
        341      00028BD4 [NONAME]
        342      00027A44 [NONAME]
        350               [NONAME] (forwarded to SHUNIMPL.#78)
        351               [NONAME] (forwarded to SHUNIMPL.#79)
        352               [NONAME] (forwarded to SHUNIMPL.#80)
        353               [NONAME] (forwarded to SHUNIMPL.#81)
        354               [NONAME] (forwarded to SHUNIMPL.#82)
        355               [NONAME] (forwarded to SHUNIMPL.#83)
        356               [NONAME] (forwarded to SHUNIMPL.#84)
        357               [NONAME] (forwarded to SHUNIMPL.#85)
        358               [NONAME] (forwarded to SHUNIMPL.#86)
        359               [NONAME] (forwarded to SHUNIMPL.#87)
        360               [NONAME] (forwarded to SHUNIMPL.#88)
        361               [NONAME] (forwarded to SHUNIMPL.#89)
        362               [NONAME] (forwarded to SHUNIMPL.#90)
        363               [NONAME] (forwarded to SHUNIMPL.#91)
        364               [NONAME] (forwarded to SHUNIMPL.#92)
        365               [NONAME] (forwarded to SHUNIMPL.#93)
        366               [NONAME] (forwarded to SHUNIMPL.#94)
        367               [NONAME] (forwarded to SHUNIMPL.#95)
        368               [NONAME] (forwarded to SHUNIMPL.#96)
        369               [NONAME] (forwarded to SHUNIMPL.#97)
        372               [NONAME] (forwarded to SHUNIMPL.#98)
        373               [NONAME] (forwarded to SHUNIMPL.#99)
        374               [NONAME] (forwarded to SHUNIMPL.#100)
        375               [NONAME] (forwarded to SHUNIMPL.#101)
        376               [NONAME] (forwarded to SHUNIMPL.#102)
        377               [NONAME] (forwarded to SHUNIMPL.#103)
        382      0000AF70 [NONAME]
        383      000228E0 [NONAME]
        384      0002B5C0 [NONAME]
        389      00079FF8 [NONAME]
        390      00078CEC [NONAME]
        402      0000980C [NONAME]
        404      00008B00 [NONAME]
        411      00022098 [NONAME]
        414      000276E8 [NONAME]
        415      000719C0 [NONAME]
        416      00071998 [NONAME]
        417      00071904 [NONAME]
        418      000718C0 [NONAME]
        419      000718D0 [NONAME]
        420      000718D0 [NONAME]
        421      00071968 [NONAME]

  Summary

        4000 .data
        5000 .pdata
        1000 .reloc
        7000 .rsrc
       8E000 .text

【讨论】:

这只是解释ComCtl32.dll 是什么,并没有解释为什么程序集需要加载和卸载数百次。 当然可以。它被 Windows 控件用于各种目的。例如,查找 CreateToolbarEx 的文档。如果 OP 的应用程序有工具栏,则可能会调用该函数。我无法具体说明,因为没有列出被调用的函数,但关键是这个 DLL 将被几乎所有 Windows 程序使用。 那么每次调用这个DLL导出的函数,整个模块就被加载和卸载了?这就是你说的吗?这似乎很浪费。调试器跟踪输出并不是说进行了函数调用,而是说模块已加载(然后卸载)。 这确实不是很有帮助。 Comtl32.dll 实现了自 Windows 95 以来的通用控件,但问题仍然是为什么加载程序先加载 DLL 然后再卸载它。如果它使用导出,它甚至不能被卸载。此行为也适用于其他 DLL。

以上是关于应用程序启动时奇怪的 comctl32.dll 加载/卸载的主要内容,如果未能解决你的问题,请参考以下文章

TaskDialog 引发异常:需要版本 6 中的 comctl32.dll

覆盖 UWP 中的 WinSxS 机制。专门针对 ComCtl32.dll

win7 comctl32.dll在哪个目录?

MFC 程序挂起:在 Vista 上更新 KB3059317 后 Comctl32.dll 损坏?

带Qt的ComCtl32.dll版本6

安装迅雷提示;损坏的图像,导致迅雷无法安装。弹出的对话框显示是:COMCTL32.dll没有被指定在windows运行