我有一个使用 WinInet 的 VC++ 应用程序。它执行以下操作:
- 调用
LoadLibrary()
加载 WinInet.dll - 来电
InternetAttemptConnect()
- 来电
InternetOpen()
- 调用
InternetConnect()
提供INTERNET_SERVICE_FTP
为dwService
如果最后一次调用失败(通常是因为传递了错误的密码)InternetConnect()
返回 0,这应该通过将错误写入日志并退出应用程序来处理。
当这种情况发生时,应用程序要求InternetCloseHandle()
关闭返回的句柄InternetOpen()
并离开WinMain()
。
之后库卸载开始 - 持有 wininet.dll 句柄的静态对象被销毁并被 WindowsFreeLibrary()
调用或FreeLibrary()
调用。在任何情况下,调用FreeLibrary()
都会挂起或崩溃。
通常它会挂起以下调用堆栈:
ntdll.dll!KiFastSystemCallRet()
ntdll.dll!NtWaitForSingleObject() + 0xc
kernel32.dll!WaitForSingleObject() + 0x12
wininet.dll!InternetInitializeAutoProxyDll() + 0xe3
wininet.dll!InternetInitializeAutoProxyDll() + 0x193e
wininet.dll!771b159d()
ntdll.dll!LdrInitializeThunk() + 0x24
ntdll.dll!LdrDisableThreadCalloutsForDll() + 0x949
kernel32.dll!FreeLibrary() + 0x19
MyApp.exe!$E5() + 0x10 C++ <-presumably the static object destructor call
msvcr71.dll!doexit(int code=0, int quick=0, int retcaller=0) Line 376 C
msvcr71.dll!exit(int code=0) Line 303 + 0xd C
MyApp.exe!wWinMainCRTStartup() Line 406 C <-entry point of my application
kernel32.dll!RegisterWaitForInputIdle() + 0x49
有时它只是崩溃而没有合理的调用堆栈显示。我想问题是 WinInet 尚未正确完成,处理这需要一些额外的操作和时间。
这种情况有解决方法吗?