views:

763

answers:

3

Hi.

How do I get the general File type description based on extention like Explorer does it? So not MIME but the information that the end-user sees, like.

.doc = Microsoft Office Word 97 - 2003 Document .zip = ZIP File .avi = Video File.

And how can I get the 'secondary' information that seems to be available, which I guess it not extention based. Like on "Video Files" it can give you the 'Length' of the movie or on doc files how many pages it has.. etc etc..

Cheers, G!

+2  A: 

Reading stuff like this directly from the registry is generally a bad idea (see Raymond Chen's blog for all the gory details). In this particular case, the API you want is AssocQueryString in shlwapi.h.

Here's C++ code:

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

You can use this from C# either via C++/CLI exposing a nice .NET-friendly API; or call it directly via P/Invoke.

Dan
+2  A: 

Thanks Dan, Alright.. This answers the first question I had. Sadly not the second. Note: Not everything prints.. Credits to 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
     }

    }
}
Gino
I think your two questions are rather unrelated.
Dan
+1  A: 

Some extra if's for unknown file types in XP.. May not really give the right results when using it with anything but FriendlyDocName, but just as an example:

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();
}
Well done Pjanssen, I just found out that the original function didn't work in XP! Good work, saved me the time of having to do it myself!
JustAPleb