Alternative à la méthode FindMimeFromData dans Urlmon.dll une qui a plus de types MIME

la FindMimeFromData méthode accessible par Windows DLL Urlmon.dll est capable de déterminer le type MIME d'une donnée stockée en mémoire, en considérant les 256 premiers octets du tableau d'octets, où de telles données sont stockées.

cependant après avoir lu sa documentation, j'ai été conduit à détection de type MIME dans Windows Internet Explorer où je pouvais trouver les types MIME que cette méthode est capable de reconnaître. Voir liste . Comme vous pouvez le voir, cette méthode est limitée à 26 types MIME.

donc je me demandais si quelqu'un pourrait me montrer une autre méthode avec plus de types MIME, ou bien une autre méthode / classe si je pouvais inclure les types MIME que je vois bon.

Merci.

6
demandé sur Fábio Antunes 2013-03-08 22:13:01

2 réponses

alors je me demandais si quelqu'un pouvait m'indiquer une autre méthode avec plus de types MIME, ou alternativement une autre méthode / classe si je le voulais être en mesure d'inclure les types MIME que je vois bon.

j'utilise un hybride de Winista et URLMon pour détecter le format réel de fichiers téléchargés..

télécharger Winista: http://www.netomatix.com/Products/DocumentManagement/MimeDetector.aspx

ou téléchargez le projet avec L'URLMon: https://github.com/MeaningOfLights/MimeDetect

Winista MIME Detection

si quelqu'un renomme un exe avec une extension jpg, vous pouvez toujours déterminer le format de fichier" réel " en utilisant L'analyse binaire. Il ne détecte pas les swf ou les flv mais fait à peu près tous les autres formats bien connus + vous pouvez obtenir un hexadécimal l'éditeur et d'ajouter plus de fichiers qu'il peut détecter.

"1519210920 Fichier" Magie

Winista détecte le type MIME réel à l'aide d'un fichier XML "mime-type.xml " qui contient des informations sur les types de fichiers et les signatures utilisées pour identifier le type de contenu.eg:

<!--
 !   Audio primary type
 ! -->

<mime-type name="audio/basic"
           description="uLaw/AU Audio File">
    <ext>au</ext><ext>snd</ext>
    <magic offset="0" type="byte" value="2e736e64000000"/>
</mime-type>

<mime-type name="audio/midi"
           description="Musical Instrument Digital Interface MIDI-sequention Sound">
    <ext>mid</ext><ext>midi</ext><ext>kar</ext>
    <magic offset="0" value="MThd"/>
</mime-type>

<mime-type name="audio/mpeg"
           description="MPEG Audio Stream, Layer III">
    <ext>mp3</ext><ext>mp2</ext><ext>mpga</ext>
    <magic offset="0" value="ID3"/>
</mime-type>

quand Winista ne détecte pas le format de fichier réel, j'ai eu recours à la méthode URLMon:

public class urlmonMimeDetect
{
    [DllImport(@"urlmon.dll", CharSet = CharSet.Auto)]
    private extern static System.UInt32 FindMimeFromData(
        System.UInt32 pBC,
        [MarshalAs(UnmanagedType.LPStr)] System.String pwzUrl,
        [MarshalAs(UnmanagedType.LPArray)] byte[] pBuffer,
        System.UInt32 cbSize,
        [MarshalAs(UnmanagedType.LPStr)] System.String pwzMimeProposed,
        System.UInt32 dwMimeFlags,
        out System.UInt32 ppwzMimeOut,
        System.UInt32 dwReserverd
    );

public string GetMimeFromFile(string filename)
{
    if (!File.Exists(filename))
        throw new FileNotFoundException(filename + " not found");

    byte[] buffer = new byte[256];
    using (FileStream fs = new FileStream(filename, FileMode.Open, FileAccess.Read))
    {
        if (fs.Length >= 256)
            fs.Read(buffer, 0, 256);
        else
            fs.Read(buffer, 0, (int)fs.Length);
    }
    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);
        return mime;
    }
    catch (Exception e)
    {
        return "unknown/unknown";
    }
}
}

de l'intérieur De la Méthode Winista, je retombe sur L'URLMon ici:

   public MimeType GetMimeTypeFromFile(string filePath)
    {
        sbyte[] fileData = null;
        using (FileStream srcFile = new FileStream(filePath, FileMode.Open, FileAccess.Read))
        {
            byte[] data = new byte[srcFile.Length];
            srcFile.Read(data, 0, (Int32)srcFile.Length);
            fileData = Winista.Mime.SupportUtil.ToSByteArray(data);
        }

        MimeType oMimeType = GetMimeType(fileData);
        if (oMimeType != null) return oMimeType;

        //We haven't found the file using Magic (eg a text/plain file)
        //so instead use URLMon to try and get the files format
        Winista.MimeDetect.URLMONMimeDetect.urlmonMimeDetect urlmonMimeDetect = new Winista.MimeDetect.URLMONMimeDetect.urlmonMimeDetect();
        string urlmonMimeType = urlmonMimeDetect.GetMimeFromFile(filePath);
        if (!string.IsNullOrEmpty(urlmonMimeType))
        {
            foreach (MimeType mimeType in types)
            {
                if (mimeType.Name == urlmonMimeType)
                {
                    return mimeType;
                }
            }
        }

        return oMimeType;
    }

Winista de netomatix . Autant que je sache, un de ses C# réécriture basée sur l'open source Java du projet au début des années 2000. Profitez-en!

vous pouvez également utiliser la méthode du registre ou .Net 4.5 méthode mentionné dans ce post lié à par Paul Zahra, mais Winista est le meilleur IMHO.

UPDATE:

pour les applications de bureau, vous pouvez trouver le WindowsAPICodePack fonctionne mieux:

using Microsoft.WindowsAPICodePack.Shell;
using Microsoft.WindowsAPICodePack.Shell.PropertySystem;

private static string GetFilePropertyItemTypeTextValueFromShellFile(string filePathWithExtension)
{
   var shellFile = ShellFile.FromFilePath(filePathWithExtension);
   var prop = shellFile.Properties.GetProperty(PItemTypeTextCanonical);
   return prop.FormatForDisplay(PropertyDescriptionFormatOptions.None);
}
13
répondu Jeremy Thompson 2018-02-26 01:14:04

il y a plusieurs solutions possibles dans ce billet qui vous donneront à tout le moins matière à réflexion.

il semble que la seule vraie façon de le faire est de le lire en binaire et ensuite faire une comparaison, si les Types MIME sont déclarés dur-codé d'une certaine façon ou vous comptez sur les machines propres types MIME disponibles / Registre.

2
répondu Paul Zahra 2017-05-23 11:51:40