potisanのプログラミングメモ

趣味のプログラマーがプログラミング関係で気になったことや調べたことをいつでも忘れられるようにメモするブログです。はてなブログ無料版なので記事の上の方はたぶん広告です。記事中にも広告挿入されるみたいです。

C# -9 Win32 API AssocGetPerceivedType関数のサンプルコード

WinAPIのAssocGetPerceivedType関数のサンプルコードです。

出力例

拡張子: .txt
PerceivedType: Text
Flags: Softcoded, NativeSupport
型: text

拡張子: .exe
PerceivedType: Application
Flags: Hardcoded
型: application

拡張子: .zip
PerceivedType: Compressed
Flags: Hardcoded, NativeSupport, ZipFolder
型: compressed

C# 9.0

using System;
using System.Diagnostics.CodeAnalysis;
using System.Runtime.InteropServices;

foreach (var extension in new[] { ".txt", ".exe", ".zip" })
{
    var result = NativeMethods.AssocGetPerceivedType(extension);
    if (result == null) continue;

    var (perceivedType, flags, typeString) = result.Value;
    Console.WriteLine("拡張子: {0}", extension);
    Console.WriteLine("PerceivedType: {0}", perceivedType.ToString());
    Console.WriteLine("Flags: {0}", flags.ToString());
    Console.WriteLine("型: {0}", typeString);
    Console.WriteLine();
}

static class NativeMethods
{
    [DllImport("shlwapi.dll", CharSet = CharSet.Unicode, ExactSpelling = true)]
    public static extern int AssocGetPerceivedType(
        [In] string pszExt,
        out PerceivedType ptype,
        out PerceivedFlag pflag,
        out IntPtr ppszType);

    [return: MaybeNull]
    public static (PerceivedType Type, PerceivedFlag Flags, string TypeString)? AssocGetPerceivedType(string extension)
    {
        var hr = NativeMethods.AssocGetPerceivedType(
            extension, out var perceivedType, out var flags, out var typePointer);
        return !IsHRError(hr)
            ? (perceivedType, flags, Marshal.PtrToStringUni(typePointer)) : null;
    }

    private static bool IsHRError(int hr) => hr < 0;
}

/// <summary>
/// PERCEIVEDTYPE
/// </summary>
public enum PerceivedType : int
{
    Custom = -3,
    Unspecified = -2,
    Folder = -1,
    Unknown = 0,
    Text = 1,
    Image = 2,
    Audio = 3,
    Video = 4,
    Compressed = 5,
    Document = 6,
    System = 7,
    Application = 8,
    GameMedia = 9,
    Contacts = 10
}

/// <summary>
/// PERCEIVEDFLAG
/// </summary>
[Flags]
public enum PerceivedFlag : int
{
    Undefined = 0x0,
    Softcoded = 0x1,
    Hardcoded = 0x2,
    NativeSupport = 0x4,
    GDIPlus = 0x10,
    WMSDK = 0x20,
    ZipFolder = 0x40
}

古いコード

Microsoft Visual C# 2017/.NET Framework 4.7

using System;
using System.Runtime.InteropServices;
using System.Security;

namespace ConsoleApp1
{
    class Program
    {
        [SuppressUnmanagedCodeSecurity]
        private static class NativeMethods
        {
            [DllImport("shlwapi.dll", CharSet = CharSet.Unicode)]
            public static extern int AssocGetPerceivedType(
                [In]string pszExt,
                out PerceivedType ptype,
                out PerceivedFlag pflag,
                out IntPtr ppszType);
        }

        /// <summary>
        /// PERCEIVEDTYPE
        /// </summary>
        public enum PerceivedType : int
        {
            Custom = -3,
            Unspecified = -2,
            Folder = -1,
            Unknown = 0,
            Text = 1,
            Image = 2,
            Audio = 3,
            Video = 4,
            Compressed = 5,
            Document = 6,
            System = 7,
            Application = 8,
            GameMedia = 9,
            Contacts = 10
        }

        /// <summary>
        /// PERCEIVEDFLAG
        /// </summary>
        [Flags]
        public enum PerceivedFlag : int
        {
            Undefined = 0x0,
            Softcoded = 0x1,
            Hardcoded = 0x2,
            NativeSupport = 0x4,
            GDIPlus = 0x10,
            WMSDK = 0x20,
            ZipFolder = 0x40
        }

        static void Main(string[] args)
        {
            var extensions = new [] { ".txt", ".exe", ".zip" };
            Array.ForEach(extensions, extension => {
                OutputExtensionPerceivedTypeInfo(extension);
                Console.WriteLine();
            });
        }

        public static void OutputExtensionPerceivedTypeInfo(string extension)
        {
            var hr = NativeMethods.AssocGetPerceivedType(
                extension, out var perceivedType, out var flags, out var typePointer);
            if (IsHRError(hr)) Marshal.ThrowExceptionForHR(hr);

            var type = Marshal.PtrToStringUni(typePointer);

            Console.WriteLine("拡張子: {0}", extension);
            Console.WriteLine("PerceivedType: {0}", perceivedType.ToString());
            Console.WriteLine("Flags: {0}", flags.ToString());
            Console.WriteLine("型: {0}", type);
        }

        public static bool IsHRError(int hr) => hr < 0;
    }
}