2009-04-20 11 views
16

Come posso ottenere la descrizione generale del tipo di file in base all'estensione come Explorer lo fa? Quindi non MIME ma le informazioni che l'utente finale vede, come.Come posso ottenere informazioni sul tipo di file in base all'estensione? (non MIME) in C#

.doc = Microsoft Office Word 97 - 2003 Documento .zip = ZIP File .avi = File video.

E come posso ottenere l'informazione "secondaria" che sembra essere disponibile, che suppongo non sia basata sull'estensione. Come su "File video" può darti la "Lunghezza" del film o su file doc quante pagine ha .. ecc. Ecc.

risposta

26

Grazie Dan, Ok .. Questo risponde alla prima domanda che ho avuto. Purtroppo non il secondo. Nota: le stampe Non tutto .. crediti verso 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

credo che la vostra due domande sono piuttosto estranei. –

4

Leggere roba del genere direttamente dal registro è in genere una cattiva idea (vedi Raymond Chen's blog per tutti gli gory details). In questo caso particolare, l'API desiderata è AssocQueryString in shlwapi.h.

Ecco codice C++:

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

È possibile utilizzare questo da C# o tramite C++/CLI esponendo un bel API .NET-friendly; o chiamarlo direttamente tramite P/Invoke.

3

Alcuni extra se di per i tipi di file sconosciuto nella XP .. possono non davvero dare i risultati giusti quando lo si utilizza con qualsiasi cosa, ma FriendlyDocName, ma solo per fare un esempio, :

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

Ben fatto Pjanssen, ho appena scoperto che la funzione originale non funzionava in XP! Buon lavoro, mi ha risparmiato il tempo di doverlo fare da solo! – JustAPleb

3

Il mio codice che includono il check per evitare alcuni errori comuni ... Speranza che aiuta :-)

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 
     } 



    } 
} 
Problemi correlati