2009-09-17 30 views
11

如何獲取使用c#的文件類型。 例如,如果在窗口資源管理器中文件名稱ID「abc.png」和文件類型將「PNG圖像」與第三列「類型」相同。在.NET中獲取文件類型

回答

11

您將需要使用Windows API SHGetFileInfo function

在輸出結構,szTypeName包含你正在尋找的名稱。

[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; 
}; 

注意,這僅僅是存儲在Windows註冊表中目前的「暱稱」,它只是一個標籤(但可能不夠好您的具體情況)。

szTypeName和szDisplayName之間的差異在MSDN描述:

szTypeName:空終止字符串即 描述文件的類型。

szDisplayName:空值終止字符串 包含該文件作爲 它出現在Windows外殼程序,或 是 含有表示 文件的圖標文件的路徑和名稱的名稱。

爲了更準確地確定文件類型,您需要讀取每個文件的第一個字節塊並將它們與發佈的文件規範進行比較。有關文件格式的信息,請參閱Wotsit之類的網站。

鏈接頁面還包含完整的示例C#代碼。

+0

您可能想糾正您的帖子 - szTypeName有信息,而不是szDisplayName。請參閱http://msdn.microsoft.com/en-us/library/aa453689.aspx => szDisplayName:以空字符結尾的字符串,其中包含文件的名稱,因爲它顯示在Windows外殼中,或者文件的路徑和名稱包含表示文件的圖標的文件。 – bobbymcr 2009-09-17 18:09:01

+0

@bobbymcr,完成,感謝您的評論。 – Ash 2009-09-18 01:08:05

10

P /調用到SHGetFileInfo,並在返回的結構中檢查szDisplayName。結果將取決於您如何定義文件類型(即,它不會是絕對引用)。但在大多數情況下應該沒問題。 Click here for the c# signature of SHGetFileInfo and example code on pinvoke.net(很棒的網站,它是)

對於絕對引用,你需要檢查二進制頭中的幾個字節的東西,並與這些字節的已知列表進行比較 - 我認爲這是如何基於Unix系統做到這一點默認。

+0

這就是unix上的'file'實用程序如何執行它,是的。 – 2009-09-17 08:14:55

2

Win-API函數SHGetFileInfo()是你的朋友。查看here的一些代碼片段。

20

您將需要P/Invoke到SHGetFileInfo來獲取文件類型信息。這裏是一個完整的示例:

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

這個答案應該是被接受的答案,因爲它也顯示瞭如何使用它,比當前接受的答案好得多。 +1 – Kaitlyn 2015-08-03 11:08:09

+0

但是,當我將文件從txt更改爲png格式時,它並不真正起作用,它告訴我這是一個PNG格式的文件。當然,該文件已經過了隱寫過程,並且使用該過程被提取,但被加密。 – Kaitlyn 2015-08-03 11:27:14

+0

謝謝你,工作很棒! – 2015-08-06 17:47:50