应用程序池在 MIME 类型检查期间因 URLMoniker urlmon.dll 而崩溃
Application pool crashes with URLMoniker urlmon.dll during MIME type checking
我的应用程序是 ASP.NET MVC 网站,部署在 Windows Server 2012 R2 上。我正在使用内置 Windows 库 URLMoniker - urlmon.dll 来获取文件的 MIME 类型。我将其文件路径传递给 GetMimeType 方法。我面临的问题是,当我使用 Visual Studio 调试它时,它 returns 该文件的 mime 类型(在我的测试案例中,对于 txt 文件,它 returns "application/octet-stream").但是在生产服务器上部署后,应用程序池意外崩溃并且日志文件中没有日志,我花了 3 天时间才找到这个代码块(借助额外的日志条目)。
private string GetMimeType(string filePath)
{
log.Info("Getting mime type for " + filePath);
byte[] buffer = new byte[256];
using (FileStream fs = new FileStream(filePath, FileMode.Open))
{
if (fs.Length >= 256)
fs.Read(buffer, 0, 256);
else
fs.Read(buffer, 0, (int)fs.Length);
}
log.Info("Done reading into byte array for " + filePath);
try
{
System.UInt32 mimetype;
FindMimeFromData(0, null, buffer, 256, null, 0, out mimetype, 0);
System.IntPtr mimeTypePtr = new IntPtr(mimetype);
string mime = Marshal.PtrToStringUni(mimeTypePtr);
Marshal.FreeCoTaskMem(mimeTypePtr);
log.Info("Got mime type for " + filePath + " " + mime);
return mime;
}
catch (Exception e)
{
log.Error("Cannot get mime type for file " + filePath, e);
return "unknown/unknown";
}
}
即使是事件查看器也没有显示应用程序池崩溃的任何原因,除了:服务于应用程序池 "SampleApp" 的进程与 Windows 进程激活服务发生致命通信错误。进程 ID 为 'yyyy'.
尽我所能进行详细研究后,我有以下文章可能会提供一些解决方案,但我仍然找不到这个问题的确切原因。
这里也遇到了类似的问题:https://superuser.com/questions/568806/iis-worker-process-crashing-without-stack-trace-what-else-can-i-try
它说 urlmon.dll 可能没有在系统上注册,但我已经检查了 windows 注册表并且它已注册。事实上,该库是最新的,我需要在对生产服务器应用任何注册表更改之前找到根本原因。用新版本替换dll,修复注册表问题是我最后的选择。 https://answers.microsoft.com/en-us/ie/forum/ie8-windows_7/urlmondll-causing-many-programs-to-crash/cda9a6cb-cf51-499c-8855-45c97110eafe
您的问题是 "FindMimeFromData" 方法的声明!
它在某些地方工作正常,但会导致 iis 进程在其他地方崩溃。看看:
您需要将 "FindMimeFromData" 的声明更改为:
[DllImport("urlmon.dll", CharSet = CharSet.Unicode, ExactSpelling = true, SetLastError = false)]static extern int FindMimeFromData(IntPtr pBC,
[MarshalAs(UnmanagedType.LPWStr)] string pwzUrl,
[MarshalAs(UnmanagedType.LPArray, ArraySubType=UnmanagedType.I1, SizeParamIndex=3)]
byte[] pBuffer,
int cbSize,
[MarshalAs(UnmanagedType.LPWStr)] string pwzMimeProposed,
int dwMimeFlags,
out IntPtr ppwzMimeOut,
int dwReserved);
并且您还应该进行一些更改以调用此函数。例如:
IntPtr mimeTypePtr;
FindMimeFromData(IntPtr.Zero, null,file, 256, null, 0,out mimeTypePtr, 0);
var mime = Marshal.PtrToStringUni(mimeTypePtr);
我的应用程序是 ASP.NET MVC 网站,部署在 Windows Server 2012 R2 上。我正在使用内置 Windows 库 URLMoniker - urlmon.dll 来获取文件的 MIME 类型。我将其文件路径传递给 GetMimeType 方法。我面临的问题是,当我使用 Visual Studio 调试它时,它 returns 该文件的 mime 类型(在我的测试案例中,对于 txt 文件,它 returns "application/octet-stream").但是在生产服务器上部署后,应用程序池意外崩溃并且日志文件中没有日志,我花了 3 天时间才找到这个代码块(借助额外的日志条目)。
private string GetMimeType(string filePath)
{
log.Info("Getting mime type for " + filePath);
byte[] buffer = new byte[256];
using (FileStream fs = new FileStream(filePath, FileMode.Open))
{
if (fs.Length >= 256)
fs.Read(buffer, 0, 256);
else
fs.Read(buffer, 0, (int)fs.Length);
}
log.Info("Done reading into byte array for " + filePath);
try
{
System.UInt32 mimetype;
FindMimeFromData(0, null, buffer, 256, null, 0, out mimetype, 0);
System.IntPtr mimeTypePtr = new IntPtr(mimetype);
string mime = Marshal.PtrToStringUni(mimeTypePtr);
Marshal.FreeCoTaskMem(mimeTypePtr);
log.Info("Got mime type for " + filePath + " " + mime);
return mime;
}
catch (Exception e)
{
log.Error("Cannot get mime type for file " + filePath, e);
return "unknown/unknown";
}
}
即使是事件查看器也没有显示应用程序池崩溃的任何原因,除了:服务于应用程序池 "SampleApp" 的进程与 Windows 进程激活服务发生致命通信错误。进程 ID 为 'yyyy'.
尽我所能进行详细研究后,我有以下文章可能会提供一些解决方案,但我仍然找不到这个问题的确切原因。
这里也遇到了类似的问题:https://superuser.com/questions/568806/iis-worker-process-crashing-without-stack-trace-what-else-can-i-try
它说 urlmon.dll 可能没有在系统上注册,但我已经检查了 windows 注册表并且它已注册。事实上,该库是最新的,我需要在对生产服务器应用任何注册表更改之前找到根本原因。用新版本替换dll,修复注册表问题是我最后的选择。 https://answers.microsoft.com/en-us/ie/forum/ie8-windows_7/urlmondll-causing-many-programs-to-crash/cda9a6cb-cf51-499c-8855-45c97110eafe
您的问题是 "FindMimeFromData" 方法的声明! 它在某些地方工作正常,但会导致 iis 进程在其他地方崩溃。看看: 您需要将 "FindMimeFromData" 的声明更改为:
[DllImport("urlmon.dll", CharSet = CharSet.Unicode, ExactSpelling = true, SetLastError = false)]static extern int FindMimeFromData(IntPtr pBC,
[MarshalAs(UnmanagedType.LPWStr)] string pwzUrl,
[MarshalAs(UnmanagedType.LPArray, ArraySubType=UnmanagedType.I1, SizeParamIndex=3)]
byte[] pBuffer,
int cbSize,
[MarshalAs(UnmanagedType.LPWStr)] string pwzMimeProposed,
int dwMimeFlags,
out IntPtr ppwzMimeOut,
int dwReserved);
并且您还应该进行一些更改以调用此函数。例如:
IntPtr mimeTypePtr;
FindMimeFromData(IntPtr.Zero, null,file, 256, null, 0,out mimeTypePtr, 0);
var mime = Marshal.PtrToStringUni(mimeTypePtr);