Jak*_*icz 4 c# winapi mime urlmon mime-types
我使用的是FindMimeFromData从urlmon.dll嗅探上传的文件的MIME类型.根据Internet Explorer中的MIME类型检测,image/tiff是一种公认的MIME类型.它在我的开发机器(Windows 7 64位,IE9)上工作正常,但在测试环境(Windows Server 2003 R2 64位,IE8)上不起作用 - 它返回application/octet-stream而不是image/tiff.
上述文章描述采取确定MIME类型的具体步骤,但由于image/tiff是在26种识别的类型中的一种,它应该结束于步骤2(嗅探的实际数据),因此,文件扩展名和注册的应用程序(和其它注册表的东西)不应该.
哦,对了,TIFF文件实际上是在测试服务器上的程序(Windows图片和传真查看器)相关联.并不是Windows注册表中没有对TIFF的任何引用.
任何想法为什么它不能按预期工作?
编辑: FindMimeFromData使用如下:
public class MimeUtil
{
[DllImport("urlmon.dll", CharSet = CharSet.Unicode, ExactSpelling = true, SetLastError = false)]
private 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);
public static string GetMimeFromData(byte[] data)
{
IntPtr mimetype = IntPtr.Zero;
try
{
const int flags = 0x20; // FMFD_RETURNUPDATEDIMGMIMES
int res = FindMimeFromData(IntPtr.Zero, null, data, data.Length, null, flags, out mimetype, 0);
switch (res)
{
case 0:
string mime = Marshal.PtrToStringUni(mimetype);
return mime;
// snip - error handling
// ...
default:
throw new Exception("Unexpected HRESULT " + res + " returned by FindMimeFromData (in urlmon.dll)");
}
}
finally
{
if (mimetype != IntPtr.Zero)
Marshal.FreeCoTaskMem(mimetype);
}
}
}
Run Code Online (Sandbox Code Playgroud)
然后像这样调用:
protected void uploader_FileUploaded(object sender, FileUploadedEventArgs e)
{
int bsize = Math.Min(e.File.ContentLength, 256);
byte[] buffer = new byte[bsize];
int nbytes = e.File.InputStream.Read(buffer, 0, bsize);
if (nbytes > 0)
string mime = MimeUtil.GetMimeFromData(buffer);
// ...
}
Run Code Online (Sandbox Code Playgroud)
我无法重现你的问题,但我对这个问题进行了一些研究.我相信它是你怀疑的,问题出在MIME类型检测的第2步:urlmon.dll v9中的硬编码测试与urlmon.dll v8中的测试不同.
关于TIFF的维基百科文章显示了格式的复杂程度,从一开始就存在问题:
引入TIFF时,其可扩展性引发了兼容性问题.编码的灵活性引发了一个笑话,即TIFF代表数千种不兼容的文件格式.
该TIFF压缩标识部分清楚地表明,我怀疑,同时创造在早期版本的IE urlmon.dll中硬编码的测试已经省略了很多难得的压缩方案.
那么,可以做些什么来解决这个问题呢?我可以想到三个解决方案,但是每个解决方案都带来了不同类型的新问题:
似乎解决方案1和2是您应该选择的解决方案.但是,生产环境可能存在问题.正如我的经验表明,生产环境的管理员经常不同意安装一些更新,原因有很多.可能更难说服管理员将IE更新为v9并更容易安装IE8 KB更新(因为他们应该这样做,但我们都知道它是怎么回事).如果您掌控生产环境,我认为您应该选择解决方案1.
第三种解决方案引入了两个问题
FindMimeFromData函数或至少自定义应用程序的清单文件.我假设您知道,将一个较新版本的urlmon.dll手动复制到系统文件夹是一个非常糟糕的主意,因为其他应用程序很可能会使用它崩溃.无论如何,好运解决你的urlmon谜语.