2009-09-17 14 views
11

Come posso ottenere il tipo di file utilizzando C#. ad esempio se un ID di file "abc.png" e il tipo di file saranno "Immagine PNG" come nella terza colonna "Tipo" in window explorer.Get tipo di file in .NET

risposta

11

Sarà necessario utilizzare l'API di Windows SHGetFileInfo function

Nella struttura di uscita, szTypeName contiene il nome che si sta cercando.

[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Auto)] 
public struct SHFILEINFO 
{ 
    public IntPtr hIcon; 
    public int iIcon; 
    public uint dwAttributes; 

    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)] 
    public string szDisplayName; 

    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 80)] 
    public string szTypeName; 
}; 

Si noti che questo è semplicemente l'attuale "Nome descrittivo", come memorizzato nel Registro di Windows, si tratta solo di un'etichetta (ma probabilmente è abbastanza buono per la vostra situazione).

La differenza tra szTypeName e szDisplayName è descritto in MSDN:

szTypeName: stringa con terminazione null che descrive il tipo di file.

szDisplayName: stringa che contiene il nome del file come appare nella shell di Windows, o il percorso e il nome del file che contiene l'icona che rappresenta il file Null-terminato.

Per una determinazione più accurata del tipo di file, è necessario leggere il primo blocco di byte di ciascun file e confrontarli con le specifiche dei file pubblicati. Vedi un sito come Wotsit per informazioni sui formati di file.

La pagina collegata contiene anche piena esempio di codice C#.

+0

Si consiglia di correggere il proprio post - szTypeName ha le informazioni, non szDisplayName. Vedi http://msdn.microsoft.com/en-us/library/aa453689.aspx => szDisplayName: stringa terminata da null che contiene il nome del file così come appare nella shell di Windows, oppure il percorso e il nome del file file che contiene l'icona che rappresenta il file. – bobbymcr

+0

@bobbymcr, fatto, grazie per il commento. – Ash

10

P/Invoke per SHGetFileInfo, e controllare szDisplayName nella struttura restituita. Il risultato dipenderà da come sono definiti i tipi di file (cioè non sarà un riferimento assoluto). Ma dovrebbe andare bene nella maggior parte dei casi. Click here for the c# signature of SHGetFileInfo and example code on pinvoke.net (sito impressionante che è)

Per un riferimento assoluto è necessario qualcosa che controlla alcuni byte nell'intestazione binaria e si confronta con un elenco noto di questi byte - Penso che sia così che i sistemi basati su Unix lo fanno per impostazione predefinita.

+0

Ecco come funziona l'utilità 'file' su unix, sì. –

2

La funzione di Win-API SHGetFileInfo() è tuo amico. Guarda here per alcuni snippet di codice.

20

Avrai bisogno di P/Invoke per SHGetFileInfo per ottenere informazioni tipo di file. Ecco un esempio completo:

using System; 
using System.Runtime.InteropServices; 

static class NativeMethods 
{ 
    [StructLayout(LayoutKind.Sequential)] 
    public struct SHFILEINFO 
    { 
     public IntPtr hIcon; 
     public int iIcon; 
     public uint dwAttributes; 
     [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)] 
     public string szDisplayName; 
     [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 80)] 
     public string szTypeName; 
    }; 

    public static class FILE_ATTRIBUTE 
    { 
     public const uint FILE_ATTRIBUTE_NORMAL = 0x80; 
    } 

    public static class SHGFI 
    { 
     public const uint SHGFI_TYPENAME = 0x000000400; 
     public const uint SHGFI_USEFILEATTRIBUTES = 0x000000010; 
    } 

    [DllImport("shell32.dll")] 
    public static extern IntPtr SHGetFileInfo(string pszPath, uint dwFileAttributes, ref SHFILEINFO psfi, uint cbSizeFileInfo, uint uFlags); 
} 

class Program 
{ 
    public static void Main(string[] args) 
    { 
     NativeMethods.SHFILEINFO info = new NativeMethods.SHFILEINFO(); 

     string fileName = @"C:\Some\Path\SomeFile.png"; 
     uint dwFileAttributes = NativeMethods.FILE_ATTRIBUTE.FILE_ATTRIBUTE_NORMAL; 
     uint uFlags = (uint)(NativeMethods.SHGFI.SHGFI_TYPENAME | NativeMethods.SHGFI.SHGFI_USEFILEATTRIBUTES); 

     NativeMethods.SHGetFileInfo(fileName, dwFileAttributes, ref info, (uint)Marshal.SizeOf(info), uFlags); 

     Console.WriteLine(info.szTypeName); 
    } 
} 
+2

Questa risposta dovrebbe essere la risposta accettata, in quanto mostra anche come utilizzarla, molto meglio della risposta corrente accettata. +1 – Kaitlyn

+0

Tuttavia, non funziona davvero, quando ho cambiato un file da txt a formato png, mi dice che è un file in formato PNG. Certo, il file ha attraversato il processo di steganografia ed è stato estratto utilizzando quel processo, ma è stato crittografato. – Kaitlyn

+0

grazie, ha funzionato alla grande! –