Tuesday, April 17, 2012

Perceived Types


Never could figure this one out complete.  We have an application that looks in the ClassesRoot Registry for the extension of a file, looking for the "PerceivedType" entry, and rendering an image if the PerceivedType is "image".  The problem for this particular computer was that its initial configuration was bad, and it had no extensions configured to image.  No idea why, nor how to automatically fix it or prevent it going forward.

Simple solution was to create a Registry merge file that included all extensions and added the "PerceivedType"="image" to all of them.  However, I stumbled onto a Windows Shell API call that would first check some hard-coded extensions for their perceived type, then check the registry, so there was potential that if our application used this call, AssocGetPerceivedType, the problem may not have surfaced in the first place.

But I could not find an example of the call defined in C# anywhere.  What a pain!  You mean no one has written C# that needs this call???????

I found C declaration for the call:

HRESULT AssocGetPerceivedType(
  __in       PCWSTR pszExt,
  __out      PERCEIVED *ptype,
  __out      PERCEIVEDFLAG *pflag,
  __out_opt  PWSTR *ppszType
    );

Now the question was, how to get it to C#?


It wasn't too hard, but did take some digging.  Below is the full code I used to get the perceived type of a file.  Simply check the returned value from the GetPerceivedType function below, passing the extension:






        [DllImport("Shlwapi", EntryPoint = "AssocGetPerceivedType")]
        private static extern int AssocGetPerceivedType(IntPtr extension, out IntPtr PERCEIVED, out IntPtr flag, out IntPtr PerceivedType);
        public string GetPerceivedType(string extension)
        {
            IntPtr result = IntPtr.Zero;
            IntPtr dummy = IntPtr.Zero;
            IntPtr intPtr_aux = Marshal.StringToHGlobalUni(extension);
            AssocGetPerceivedType(intPtr_aux, out dummy, out dummy, out result);
            string s = Marshal.PtrToStringAuto(result);
            return s;
        }
        

No comments:

Post a Comment