2009-04-20 9 views
16

Wie bekomme ich die allgemeine Dateityp Beschreibung basierend auf Erweiterung wie Explorer tut es? Also nicht MIME, sondern die Informationen, die der Endanwender sieht.Wie erhalte ich Dateitypinformationen basierend auf der Erweiterung? (nicht MIME) in C#

.doc = Microsoft Office Word 97 - 2003 Dokument .zip = ZIP-Datei .avi = Videodatei.

Und wie bekomme ich die "sekundären" Informationen, die verfügbar zu sein scheinen, die ich denke, dass es nicht extensionsbasiert ist. Wie bei "Videodateien" kann es die "Länge" des Films oder auf doc-Dateien geben, wie viele Seiten es hat .. usw.

Antwort

26

Danke Dan, in Ordnung. Dies beantwortet die erste Frage, die ich hatte. Leider nicht die zweite. Hinweis: Nicht alles druckt .. Credits PInvoke.net

using System; 
using System.Runtime.InteropServices; 
using System.Text; 
using System.Diagnostics; 


namespace WindowsFormsApplication1 
{ 
    static class Program 
    { 
     [DllImport("Shlwapi.dll", SetLastError = true, CharSet = CharSet.Auto)] 
     static extern uint AssocQueryString(AssocF flags, AssocStr str, string pszAssoc, string pszExtra, [Out] StringBuilder pszOut, [In][Out] ref uint pcchOut); 

     /// <summary> 
     /// The main entry point for the application. 
     /// </summary> 
     [STAThread] 
     static void Main() 
     { 
      Debug.WriteLine(FileExtentionInfo(AssocStr.Command, ".doc"), "Command"); 
      Debug.WriteLine(FileExtentionInfo(AssocStr.DDEApplication, ".doc"), "DDEApplication"); 
      Debug.WriteLine(FileExtentionInfo(AssocStr.DDEIfExec, ".doc"), "DDEIfExec"); 
      Debug.WriteLine(FileExtentionInfo(AssocStr.DDETopic, ".doc"), "DDETopic"); 
      Debug.WriteLine(FileExtentionInfo(AssocStr.Executable, ".doc"), "Executable"); 
      Debug.WriteLine(FileExtentionInfo(AssocStr.FriendlyAppName, ".doc"), "FriendlyAppName"); 
      Debug.WriteLine(FileExtentionInfo(AssocStr.FriendlyDocName, ".doc"), "FriendlyDocName"); 
      Debug.WriteLine(FileExtentionInfo(AssocStr.NoOpen, ".doc"), "NoOpen"); 
      Debug.WriteLine(FileExtentionInfo(AssocStr.ShellNewValue, ".doc"), "ShellNewValue"); 

      // DDEApplication: WinWord 
      //DDEIfExec: Ñﻴ߾ 
      // DDETopic: System 
      // Executable: C:\Program Files (x86)\Microsoft Office\Office12\WINWORD.EXE 
      // FriendlyAppName: Microsoft Office Word 
      // FriendlyDocName: Microsoft Office Word 97 - 2003 Document 


     } 

     public static string FileExtentionInfo(AssocStr assocStr, string doctype) 
     { 
      uint pcchOut = 0; 
      AssocQueryString(AssocF.Verify, assocStr, doctype, null, null, ref pcchOut); 

      StringBuilder pszOut = new StringBuilder((int)pcchOut); 
      AssocQueryString(AssocF.Verify, assocStr, doctype, null, pszOut, ref pcchOut); 
      return pszOut.ToString(); 
     } 

     [Flags] 
     public enum AssocF 
     { 
      Init_NoRemapCLSID = 0x1, 
      Init_ByExeName = 0x2, 
      Open_ByExeName = 0x2, 
      Init_DefaultToStar = 0x4, 
      Init_DefaultToFolder = 0x8, 
      NoUserSettings = 0x10, 
      NoTruncate = 0x20, 
      Verify = 0x40, 
      RemapRunDll = 0x80, 
      NoFixUps = 0x100, 
      IgnoreBaseClass = 0x200 
     } 

     public enum AssocStr 
     { 
      Command = 1, 
      Executable, 
      FriendlyDocName, 
      FriendlyAppName, 
      NoOpen, 
      ShellNewValue, 
      DDECommand, 
      DDEIfExec, 
      DDEApplication, 
      DDETopic 
     } 

    } 
} 
+0

ich Ihre beiden Fragen denken sind nicht miteinander verwandt. –

4

Lesen Zeug wie diese direkt aus der Registrierung ist in der Regel eine schlechte Idee (siehe Raymond Chen's blog für alle gory details). In diesem speziellen Fall lautet die von Ihnen gewünschte API AssocQueryString in shlwapi.h.

Hier ist C++ Code:

TCHAR buf[1024]; 
DWORD sz = sizeof(buf)/sizeof(TCHAR); 
AssocQueryString(ASSOCF_INIT_DEFAULTTOSTAR, ASSOCSTR_FRIENDLYDOCNAME, L".sql", NULL, buf, &sz); 

du von C# verwenden kann entweder über C++/CLI eine schöne .NET freundliche API ausgesetzt werden; oder rufen Sie direkt über P/Invoke.

3

Einige extra, wenn die für unbekannte Dateitypen in XP .. kann nicht wirklich die richtigen Ergebnisse, wenn es mit alles andere als FriendlyDocName verwenden, sondern nur als ein Beispiel :

public static string FileExtentionInfo(AssocStr assocStr, string doctype) 
{ 
    if ((doctype.Length <= 1) || !doctype.StartsWith(".")) return ""; 

    uint pcchOut = 0; 
    AssocQueryString(AssocF.Verify, assocStr, doctype, null, null, ref pcchOut); 

    if (pcchOut == 0) return (doctype.Trim('.').ToUpper() + " File"); 

    StringBuilder pszOut = new StringBuilder((int)pcchOut); 
    AssocQueryString(AssocF.Verify, assocStr, doctype, null, pszOut, ref pcchOut); 
    return pszOut.ToString(); 
} 
+0

Gut gemacht Pjanssen, ich habe gerade herausgefunden, dass die ursprüngliche Funktion in XP nicht funktionierte! Gute Arbeit, rettete mir die Zeit, es selbst zu tun! – JustAPleb

3

Mein Code, der von einigen gemeinsamen Fehler zu vermeiden sind prüfen ... Hoffe, es hilft :-)

using System; 
using System.Diagnostics; 
using System.IO; 
using System.Runtime.InteropServices; 
using System.Text; 

namespace HQ.Util.Unmanaged 
{ 
    /// <summary> 
    /// Usage: string executablePath = FileAssociation.GetExecFileAssociatedToExtension(pathExtension, "open"); 
    /// </summary> 
    public static class FileAssociation 
    { 
     /// <summary> 
     /// 
     /// </summary> 
     /// <param name="ext"></param> 
     /// <param name="verb"></param> 
     /// <returns>Return null if not found</returns> 
     public static string GetExecFileAssociatedToExtension(string ext, string verb = null) 
     { 
      if (ext[0] != '.') 
      { 
       ext = "." + ext; 
      } 

      string executablePath = FileExtentionInfo(AssocStr.Executable, ext, verb); // Will only work for 'open' verb 
      if (string.IsNullOrEmpty(executablePath)) 
      { 
       executablePath = FileExtentionInfo(AssocStr.Command, ext, verb); // required to find command of any other verb than 'open' 

       // Extract only the path 
       if (!string.IsNullOrEmpty(executablePath) && executablePath.Length > 1) 
       { 
        if (executablePath[0] == '"') 
        { 
         executablePath = executablePath.Split('\"')[1]; 
        } 
        else if (executablePath[0] == '\'') 
        { 
         executablePath = executablePath.Split('\'')[1]; 
        } 
       } 
      } 

      // Ensure to not return the default OpenWith.exe associated executable in Windows 8 or higher 
      if (!string.IsNullOrEmpty(executablePath) && File.Exists(executablePath) && 
       !executablePath.ToLower().EndsWith(".dll")) 
      { 
       if (executablePath.ToLower().EndsWith("openwith.exe")) 
       { 
        return null; // 'OpenWith.exe' is th windows 8 or higher default for unknown extensions. I don't want to have it as associted file 
       } 
       return executablePath; 
      } 
      return executablePath; 
     } 

     [DllImport("Shlwapi.dll", SetLastError = true, CharSet = CharSet.Auto)] 
     static extern uint AssocQueryString(AssocF flags, AssocStr str, string pszAssoc, string pszExtra, [Out] StringBuilder pszOut, [In][Out] ref uint pcchOut); 

     private static string FileExtentionInfo(AssocStr assocStr, string doctype, string verb) 
     { 
      uint pcchOut = 0; 
      AssocQueryString(AssocF.Verify, assocStr, doctype, verb, null, ref pcchOut); 

      Debug.Assert(pcchOut != 0); 
      if (pcchOut == 0) 
      { 
       return ""; 
      } 

      StringBuilder pszOut = new StringBuilder((int)pcchOut); 
      AssocQueryString(AssocF.Verify, assocStr, doctype, verb, pszOut, ref pcchOut); 
      return pszOut.ToString(); 
     } 

     [Flags] 
     public enum AssocF 
     { 
      Init_NoRemapCLSID = 0x1, 
      Init_ByExeName = 0x2, 
      Open_ByExeName = 0x2, 
      Init_DefaultToStar = 0x4, 
      Init_DefaultToFolder = 0x8, 
      NoUserSettings = 0x10, 
      NoTruncate = 0x20, 
      Verify = 0x40, 
      RemapRunDll = 0x80, 
      NoFixUps = 0x100, 
      IgnoreBaseClass = 0x200 
     } 

     public enum AssocStr 
     { 
      Command = 1, 
      Executable, 
      FriendlyDocName, 
      FriendlyAppName, 
      NoOpen, 
      ShellNewValue, 
      DDECommand, 
      DDEIfExec, 
      DDEApplication, 
      DDETopic 
     } 



    } 
}