Detect if headphones are plugged in or not via C#

后端 未结 3 1531
不知归路
不知归路 2020-12-02 21:53

There is no example how to detect if headphones are plugged in or not via C#.

I assume should be some event for that...

Does make sense to use WMI?



        
3条回答
  •  Happy的楠姐
    2020-12-02 22:15

    Below is a (minimal) Windows Forms application sample based on the IMMNotificationClient interface which does not require any third-party library.

    You will receive a notification whenever a multimedia device is plugged/unplugged. You can then look at the device properties and take the appropriate action. You are also able to enumerate existing devices and check whether a headphone is plugged (see the IsConnected property).

    Creating COM Interop

    Note that the sample code includes the definition of the relevant COM object. In production, I would probably create a COM interop assembly for the underlying mmdevapi.dll. You can do so by first creating a type lib from the header files (Windows SDK needs to be installed):

    midl /out c:\tmp /header "C:\Program Files (x86)\Windows Kits\8.1\Include\um\mmdeviceapi.h" "C:\Program Files (x86)\Windows Kits\8.1\Include\um\mmdeviceapi.idl"
    

    Then you need to generate the interop assembly from the typelib using tlbimp.exe:

    tlbimp /out:MMDevAPI.Interop.dll mmdeviceapi.tlb
    

    MultiMediaNotificationListener Sample

    using System;
    using System.Runtime.InteropServices;
    using System.Collections.Generic;
    using System.Diagnostics;
    using System.Linq;
    using System.Reflection;
    using System.Runtime.CompilerServices;
    using System.Windows.Forms;
    
    namespace MultiMediaNotificationListenerSample
    {
        class MainWindow : Form
        {
            [STAThread]
            private static void Main(string[] args)
            {
                using (var notificationClient = new MultiMediaNotificationListener())
                {
                    Trace.WriteLine(string.Format("Headphone is {0}connected", notificationClient.IsConnected ? "": "not "));
                    Application.Run(new MainWindow());
                }
            }
        }
    
        class MultiMediaNotificationListener : IMMNotificationClient, IDisposable
        {
            private readonly IMMDeviceEnumerator _deviceEnumerator;
    
            public MultiMediaNotificationListener()
            {
                if (Environment.OSVersion.Version.Major < 6)
                {
                    throw new NotSupportedException("This functionality is only supported on Windows Vista or newer.");
                }
                _deviceEnumerator = (IMMDeviceEnumerator)new MMDeviceEnumerator();
                _deviceEnumerator.RegisterEndpointNotificationCallback(this);
            }
    
            ~MultiMediaNotificationListener()
            {
                Dispose(false);
            }
    
            public bool IsConnected
            {
                get
                {
                    IMMDeviceCollection deviceCollection;
                    _deviceEnumerator.EnumAudioEndpoints(EDataFlow.eRender, (uint)DeviceState.DEVICE_STATE_ACTIVE, out deviceCollection);
    
                    uint deviceCount = 0;
                    deviceCollection.GetCount(out deviceCount);
                    for (uint i = 0; i < deviceCount; i++)
                    {
                        IMMDevice device;
                        deviceCollection.Item(i, out device);
    
                        IPropertyStore propertyStore;
                        device.OpenPropertyStore((uint)STGM.STGM_READ, out propertyStore);
    
                        PROPVARIANT property;
                        propertyStore.GetValue(ref PropertyKey.PKEY_Device_DeviceDesc, out property);
    
                        var value = (string)property.Value;
                        Marshal.ReleaseComObject(propertyStore);
                        Marshal.ReleaseComObject(device);
    
                        if (value == "Headphones")
                        {
                            return true;
                        }
                    }
    
                    Marshal.ReleaseComObject(deviceCollection);
                    return false;
                }
            }
    
            public void OnDefaultDeviceChanged(EDataFlow dataFlow, ERole deviceRole, string pwstrDefaultDeviceId)
            {
            }
    
            public void OnDeviceStateChanged(string pwstrDeviceId, uint dwNewState)
            {
                IMMDevice device;
                _deviceEnumerator.GetDevice(pwstrDeviceId, out device);
    
                IPropertyStore propertyStore;
                device.OpenPropertyStore((uint)STGM.STGM_READ, out propertyStore);
    
                Trace.WriteLine(string.Format("OnDeviceStateChanged:\n  Device Id {0}\tDevice State {1}", pwstrDeviceId, (DeviceState)dwNewState));
    
                var properties = PropertyKey.GetPropertyKeys()
                    .Select(
                    propertyKey =>
                    {
                        PROPVARIANT property;
                        propertyStore.GetValue(ref propertyKey, out property);
                        return new { Key = PropertyKey.GetKeyName(propertyKey), Value = property.Value };
                    })
                    .Where(@t => @t.Value != null);
    
                foreach (var property in properties)
                {
                    Trace.WriteLine(string.Format("    {0}\t{1}", property.Key, property.Value));
                }
    
                Marshal.ReleaseComObject(propertyStore);
                Marshal.ReleaseComObject(device);
            }
    
            public void OnDeviceAdded(string deviceId)
            {
            }
    
            public void OnDeviceRemoved(string deviceId)
            {
            }
    
            public void OnPropertyValueChanged(string pwstrDeviceId, PropertyKey key)
            {
            }
    
            public void Dispose()
            {
                Dispose(true);
                GC.SuppressFinalize(this);
            }
    
            private void Dispose(bool disposing)
            {
                _deviceEnumerator.UnregisterEndpointNotificationCallback(this);
                Marshal.ReleaseComObject(_deviceEnumerator);
            }
        }
    
        public enum STGM : uint
        {
            STGM_READ = 0x0,
            STGM_WRITE = 0x1,
            STGM_READWRITE = 0x2
        }
    
        public enum DeviceState
        {
            DEVICE_STATE_ACTIVE = 0x00000001,
            DEVICE_STATE_DISABLED = 0x00000002,
            DEVICE_STATE_NOTPRESENT = 0x00000004,
            DEVICE_STATE_UNPLUGGED = 0x00000008,
            DEVICE_STATEMASK_ALL = 0x0000000f
        }
    
        [ComImport]
        [Guid("BCDE0395-E52F-467C-8E3D-C4579291692E")]
        internal class MMDeviceEnumerator
        {
        }
    
        public enum EDataFlow
        {
            eRender,
            eCapture,
            eAll,
            EDataFlow_enum_count
        }
    
        public enum ERole
        {
            eConsole,
            eMultimedia,
            eCommunications,
            ERole_enum_count
        }
    
        [Guid("0BD7A1BE-7A1A-44DB-8397-CC5392387B5E"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown), TypeLibType(TypeLibTypeFlags.FNonExtensible)]
        [ComImport]
        public interface IMMDeviceCollection
        {
            [MethodImpl(MethodImplOptions.InternalCall)]
            void GetCount(out uint pcDevices);
            [MethodImpl(MethodImplOptions.InternalCall)]
            void Item([In] uint nDevice, [MarshalAs(UnmanagedType.Interface)] out IMMDevice ppDevice);
        }
    
        [Guid("A95664D2-9614-4F35-A746-DE8DB63617E6"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown), TypeLibType(TypeLibTypeFlags.FNonExtensible)]
        [ComImport]
        public interface IMMDeviceEnumerator
        {
            [MethodImpl(MethodImplOptions.InternalCall)]
            void EnumAudioEndpoints([ComAliasName("MMDevAPI.Interop.EDataFlow")] [In] EDataFlow dataFlow, [In] uint dwStateMask, [MarshalAs(UnmanagedType.Interface)] out IMMDeviceCollection ppDevices);
            [MethodImpl(MethodImplOptions.InternalCall)]
            void GetDefaultAudioEndpoint([ComAliasName("MMDevAPI.Interop.EDataFlow")] [In] EDataFlow dataFlow, [ComAliasName("MMDevAPI.Interop.ERole")] [In] ERole role, [MarshalAs(UnmanagedType.Interface)] out IMMDevice ppEndpoint);
            [MethodImpl(MethodImplOptions.InternalCall)]
            void GetDevice([MarshalAs(UnmanagedType.LPWStr)] [In] string pwstrId, [MarshalAs(UnmanagedType.Interface)] out IMMDevice ppDevice);
            [MethodImpl(MethodImplOptions.InternalCall)]
            void RegisterEndpointNotificationCallback([MarshalAs(UnmanagedType.Interface)] [In] IMMNotificationClient pClient);
            [MethodImpl(MethodImplOptions.InternalCall)]
            void UnregisterEndpointNotificationCallback([MarshalAs(UnmanagedType.Interface)] [In] IMMNotificationClient pClient);
        }
    
        [Guid("D666063F-1587-4E43-81F1-B948E807363F"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown), TypeLibType(TypeLibTypeFlags.FNonExtensible)]
        [ComImport]
        public interface IMMDevice
        {
            [MethodImpl(MethodImplOptions.InternalCall)]
            void Activate([In] ref Guid iid, [In] uint dwClsCtx, [In] IntPtr pActivationParams, [MarshalAs(UnmanagedType.IUnknown)] out object ppInterface);
            [MethodImpl(MethodImplOptions.InternalCall)]
            void OpenPropertyStore([In] uint stgmAccess, [MarshalAs(UnmanagedType.Interface)] out IPropertyStore ppProperties);
            [MethodImpl(MethodImplOptions.InternalCall)]
            void GetId([MarshalAs(UnmanagedType.LPWStr)] out string ppstrId);
            [MethodImpl(MethodImplOptions.InternalCall)]
            void GetState(out uint pdwState);
        }
    
        [Guid("7991EEC9-7E89-4D85-8390-6C703CEC60C0"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown), TypeLibType(TypeLibTypeFlags.FNonExtensible)]
        [ComImport]
        public interface IMMNotificationClient
        {
            [MethodImpl(MethodImplOptions.InternalCall)]
            void OnDeviceStateChanged([MarshalAs(UnmanagedType.LPWStr)] [In] string pwstrDeviceId, [In] uint dwNewState);
            [MethodImpl(MethodImplOptions.InternalCall)]
            void OnDeviceAdded([MarshalAs(UnmanagedType.LPWStr)] [In] string pwstrDeviceId);
            [MethodImpl(MethodImplOptions.InternalCall)]
            void OnDeviceRemoved([MarshalAs(UnmanagedType.LPWStr)] [In] string pwstrDeviceId);
            [MethodImpl(MethodImplOptions.InternalCall)]
            void OnDefaultDeviceChanged([ComAliasName("MMDevAPI.Interop.EDataFlow")] [In] EDataFlow flow, [ComAliasName("MMDevAPI.Interop.ERole")] [In] ERole role, [MarshalAs(UnmanagedType.LPWStr)] [In] string pwstrDefaultDeviceId);
            [MethodImpl(MethodImplOptions.InternalCall)]
            void OnPropertyValueChanged([MarshalAs(UnmanagedType.LPWStr)] [In] string pwstrDeviceId, [In] PropertyKey key);
        }
    
        [Guid("886D8EEB-8CF2-4446-8D02-CDBA1DBDCF99"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
        [ComImport]
        public interface IPropertyStore
        {
            [MethodImpl(MethodImplOptions.InternalCall)]
            void GetCount(out uint cProps);
            [MethodImpl(MethodImplOptions.InternalCall)]
            void GetAt([In] uint iProp, out PropertyKey pkey);
            [MethodImpl(MethodImplOptions.InternalCall)]
            void GetValue([In] ref PropertyKey key, out PROPVARIANT pv);
            [MethodImpl(MethodImplOptions.InternalCall)]
            void SetValue([In] ref PropertyKey key, [In] ref PROPVARIANT propvar);
            [MethodImpl(MethodImplOptions.InternalCall)]
            void Commit();
        }
    
        [StructLayout(LayoutKind.Sequential, Pack = 4)]
        public struct PropertyKey
        {
            public static PropertyKey PKEY_Device_DeviceDesc = new PropertyKey { fmtid = new Guid(unchecked((int)0xa45c254e), unchecked((short)0xdf1c), 0x4efd, 0x80, 0x20, 0x67, 0xd1, 0x46, 0xa8, 0x50, 0xe0), pid = 2 }; // DEVPROP_TYPE_STRING
            public static PropertyKey PKEY_Device_HardwareIds = new PropertyKey { fmtid = new Guid(unchecked((int)0xa45c254e), unchecked((short)0xdf1c), 0x4efd, 0x80, 0x20, 0x67, 0xd1, 0x46, 0xa8, 0x50, 0xe0), pid = 3 }; // DEVPROP_TYPE_STRING_LIST
            public static PropertyKey PKEY_Device_Service = new PropertyKey { fmtid = new Guid(unchecked((int)0xa45c254e), unchecked((short)0xdf1c), 0x4efd, 0x80, 0x20, 0x67, 0xd1, 0x46, 0xa8, 0x50, 0xe0), pid = 6 }; // DEVPROP_TYPE_STRING
            public static PropertyKey PKEY_Device_Class = new PropertyKey { fmtid = new Guid(unchecked((int)0xa45c254e), unchecked((short)0xdf1c), 0x4efd, 0x80, 0x20, 0x67, 0xd1, 0x46, 0xa8, 0x50, 0xe0), pid = 9 }; // DEVPROP_TYPE_STRING
            public static PropertyKey PKEY_Device_Driver = new PropertyKey { fmtid = new Guid(unchecked((int)0xa45c254e), unchecked((short)0xdf1c), 0x4efd, 0x80, 0x20, 0x67, 0xd1, 0x46, 0xa8, 0x50, 0xe0), pid = 11 }; // DEVPROP_TYPE_STRING
            public static PropertyKey PKEY_Device_ConfigFlags = new PropertyKey { fmtid = new Guid(unchecked((int)0xa45c254e), unchecked((short)0xdf1c), 0x4efd, 0x80, 0x20, 0x67, 0xd1, 0x46, 0xa8, 0x50, 0xe0), pid = 12 }; // DEVPROP_TYPE_UINT32
            public static PropertyKey PKEY_Device_Manufacturer = new PropertyKey { fmtid = new Guid(unchecked((int)0xa45c254e), unchecked((short)0xdf1c), 0x4efd, 0x80, 0x20, 0x67, 0xd1, 0x46, 0xa8, 0x50, 0xe0), pid = 13 }; // DEVPROP_TYPE_STRING
            public static PropertyKey PKEY_Device_FriendlyName = new PropertyKey { fmtid = new Guid(unchecked((int)0xa45c254e), unchecked((short)0xdf1c), 0x4efd, 0x80, 0x20, 0x67, 0xd1, 0x46, 0xa8, 0x50, 0xe0), pid = 14 }; // DEVPROP_TYPE_STRING
            public static PropertyKey PKEY_Device_LocationInfo = new PropertyKey { fmtid = new Guid(unchecked((int)0xa45c254e), unchecked((short)0xdf1c), 0x4efd, 0x80, 0x20, 0x67, 0xd1, 0x46, 0xa8, 0x50, 0xe0), pid = 15 }; // DEVPROP_TYPE_STRING
            public static PropertyKey PKEY_Device_Capabilities = new PropertyKey { fmtid = new Guid(unchecked((int)0xa45c254e), unchecked((short)0xdf1c), 0x4efd, 0x80, 0x20, 0x67, 0xd1, 0x46, 0xa8, 0x50, 0xe0), pid = 17 }; // DEVPROP_TYPE_UNINT32
            public static PropertyKey PKEY_Device_BusNumber = new PropertyKey { fmtid = new Guid(unchecked((int)0xa45c254e), unchecked((short)0xdf1c), 0x4efd, 0x80, 0x20, 0x67, 0xd1, 0x46, 0xa8, 0x50, 0xe0), pid = 23 }; // DEVPROP_TYPE_UINT32
            public static PropertyKey PKEY_Device_EnumeratorName = new PropertyKey { fmtid = new Guid(unchecked((int)0xa45c254e), unchecked((short)0xdf1c), 0x4efd, 0x80, 0x20, 0x67, 0xd1, 0x46, 0xa8, 0x50, 0xe0), pid = 24 }; // DEVPROP_TYPE_STRING
            public static PropertyKey PKEY_Device_DevType = new PropertyKey { fmtid = new Guid(unchecked((int)0xa45c254e), unchecked((short)0xdf1c), 0x4efd, 0x80, 0x20, 0x67, 0xd1, 0x46, 0xa8, 0x50, 0xe0), pid = 27 }; // DEVPROP_TYPE_UINT32
            public static PropertyKey PKEY_Device_Characteristics = new PropertyKey { fmtid = new Guid(unchecked((int)0xa45c254e), unchecked((short)0xdf1c), 0x4efd, 0x80, 0x20, 0x67, 0xd1, 0x46, 0xa8, 0x50, 0xe0), pid = 29 }; // DEVPROP_TYPE_UINT32
    
    
            public static PropertyKey PKEY_Device_ManufacturerAttributes = new PropertyKey { fmtid = new Guid(unchecked((int)0x80d81ea6), unchecked((short)0x7473), 0x4b0c, 0x82, 0x16, 0xef, 0xc1, 0x1a, 0x2c, 0x4c, 0x8b), pid = 4 }; // DEVPROP_TYPE_UINT32
    
            public static PropertyKey PKEY_DeviceClass_IconPath = new PropertyKey { fmtid = new Guid(unchecked((int)0x259abffc), 0x50a7, 0x47ce, 0xaf, 0x8, 0x68, 0xc9, 0xa7, 0xd7, 0x33, 0x66), pid = 12 }; // DEVPROP_TYPE_STRING_LIST
    
            public static PropertyKey PKEY_DeviceClass_ClassCoInstallers = new PropertyKey { fmtid = new Guid(unchecked((int)0x713d1703), 0xa2e2, 0x49f5, 0x92, 0x14, 0x56, 0x47, 0x2e, 0xf3, 0xda, 0x5c), pid = 2 }; // DEVPROP_TYPE_STRING_LIST
    
            public static PropertyKey PKEY_DeviceInterface_FriendlyName = new PropertyKey { fmtid = new Guid(unchecked((int)0x026e516e), 0xb814, 0x414b, 0x83, 0xcd, 0x85, 0x6d, 0x6f, 0xef, 0x48, 0x22), pid = 2 }; // DEVPROP_TYPE_STRING
    
            public Guid fmtid;
            public uint pid;
    
            public static IEnumerable GetPropertyKeys()
            {
                var keyFields = typeof(PropertyKey).GetFields(BindingFlags.Public | BindingFlags.Static);
                return keyFields.Where(fieldInfo => fieldInfo.FieldType == typeof(PropertyKey))
                                .Select(fieldInfo => (PropertyKey)fieldInfo.GetValue(null));
            }
    
            public static string GetKeyName(PropertyKey propertyKey)
            {
                var keyFields = typeof(PropertyKey).GetFields(BindingFlags.Public | BindingFlags.Static);
                return keyFields.Select(fieldInfo => new { fieldInfo, value = (PropertyKey)fieldInfo.GetValue(null) })
                                .Where(@t => propertyKey.pid == @t.value.pid && propertyKey.fmtid == @t.value.fmtid)
                                .Select(@t => @t.fieldInfo.Name).FirstOrDefault();
            }
        }
    
        [StructLayout(LayoutKind.Sequential, Pack = 8)]
        public struct PROPVARIANT
        {
            public ushort variantType;
            public byte wReserved1;
            public byte wReserved2;
            public uint wReserved3;
            public PROPVARIANTVALUE value;
    
            public object Value
            {
                get
                {
                    switch ((VarEnum)variantType)
                    {
                        case VarEnum.VT_EMPTY:
                            return null;
                        case VarEnum.VT_NULL:
                            return null;
                        case VarEnum.VT_VARIANT:
                            break;
                        case VarEnum.VT_DECIMAL:
                            return value.cyVal;
                        case VarEnum.VT_VOID:
                            break;
                        case VarEnum.VT_HRESULT:
                            break;
                        case VarEnum.VT_PTR:
                            break;
                        case VarEnum.VT_SAFEARRAY:
                            break;
                        case VarEnum.VT_CARRAY:
                            break;
                        case VarEnum.VT_USERDEFINED:
                            break;
                        case VarEnum.VT_RECORD:
                            break;
                        case VarEnum.VT_STREAM:
                            break;
                        case VarEnum.VT_STORAGE:
                            break;
                        case VarEnum.VT_STREAMED_OBJECT:
                            break;
                        case VarEnum.VT_STORED_OBJECT:
                            break;
                        case VarEnum.VT_BLOB_OBJECT:
                            break;
                        case VarEnum.VT_CF:
                            break;
                        case VarEnum.VT_CLSID:
                            return Marshal.PtrToStructure(value.pVal, typeof(Guid));
                        case VarEnum.VT_VECTOR:
                            break;
                        case VarEnum.VT_ARRAY:
                            break;
                        case VarEnum.VT_BYREF:
                            break;
                        case VarEnum.VT_I1:
                            return value.cVal;
                        case VarEnum.VT_UI1:
                            return value.bVal;
                        case VarEnum.VT_I2:
                            return value.iVal;
                        case VarEnum.VT_UI2:
                            return value.uiVal;
                        case VarEnum.VT_I4:
                        case VarEnum.VT_INT:
                            return value.intVal;
                        case VarEnum.VT_UI4:
                        case VarEnum.VT_UINT:
                            return value.uintVal;
                        case VarEnum.VT_I8:
                            return value.hVal;
                        case VarEnum.VT_UI8:
                            return value.uhVal;
                        case VarEnum.VT_R4:
                            return value.fltVal;
                        case VarEnum.VT_R8:
                            return value.dblVal;
                        case VarEnum.VT_BOOL:
                            return value.boolVal;
                        case VarEnum.VT_ERROR:
                            return value.scode;
                        case VarEnum.VT_CY:
                            return value.cyVal;
                        case VarEnum.VT_DATE:
                            return value.date;
                        case VarEnum.VT_FILETIME:
                            return DateTime.FromFileTime(value.hVal);
                        case VarEnum.VT_BSTR:
                            return Marshal.PtrToStringBSTR(value.pVal);
                        case VarEnum.VT_BLOB:
                            var blob = value.blob;
                            var blobData = new byte[blob.cbSize];
                            Marshal.Copy(blob.pBlobData, blobData, 0, (int)blob.cbSize);
                            return blobData;
                        case VarEnum.VT_LPSTR:
                            return Marshal.PtrToStringAnsi(value.pVal);
                        case VarEnum.VT_LPWSTR:
                            return Marshal.PtrToStringUni(value.pVal);
                        case VarEnum.VT_UNKNOWN:
                            return Marshal.GetObjectForIUnknown(value.pVal);
                        case VarEnum.VT_DISPATCH:
                            return value.pVal;
                        //default:
                        //    throw new NotSupportedException("The type of this variable is not support ('" + variantType + "')");
                    }
                    return string.Format("unsupported {0}", ((VarEnum)variantType));
                    //throw new NotSupportedException("The type of this variable is not support ('" + variantType.ToString() + "')");
                }
            }
        }
    
        [ComConversionLoss]
        [StructLayout(LayoutKind.Explicit, Pack = 8, Size = 8)]
        public struct PROPVARIANTVALUE
        {
            [FieldOffset(0)]
            public sbyte cVal;
            [FieldOffset(0)]
            public byte bVal;
            [FieldOffset(0)]
            public short iVal;
            [FieldOffset(0)]
            public ushort uiVal;
            [FieldOffset(0)]
            public int intVal;
            [FieldOffset(0)]
            public uint uintVal;
            [FieldOffset(0)]
            public long hVal;
            [FieldOffset(0)]
            public ulong uhVal;
            [FieldOffset(0)]
            public float fltVal;
            [FieldOffset(0)]
            public double dblVal;
            [FieldOffset(0)]
            public short boolVal;
            [FieldOffset(0)]
            [MarshalAs(UnmanagedType.Error)]
            public int scode;
            [FieldOffset(0)]
            [MarshalAs(UnmanagedType.Currency)]
            public decimal cyVal;
            [FieldOffset(0)]
            public DateTime date;
            [FieldOffset(0)]
            public tagFILETIME filetime;
            [FieldOffset(0)]
            public tagARRAY array;
            [FieldOffset(0)]
            public tagBLOB blob;
            [ComConversionLoss]
            [FieldOffset(0)]
            public IntPtr pVal;
        }
    
        [ComConversionLoss]
        [StructLayout(LayoutKind.Sequential, Pack = 4)]
        public struct tagARRAY
        {
            public uint cElems;
            [ComConversionLoss]
            public IntPtr pElems;
        }
    
        [ComConversionLoss]
        [StructLayout(LayoutKind.Sequential, Pack = 4)]
        public struct tagBLOB
        {
            public uint cbSize;
            [ComConversionLoss]
            public IntPtr pBlobData;
        }
    
        [StructLayout(LayoutKind.Sequential, Pack = 4)]
        public struct tagFILETIME
        {
            public uint dwLowDateTime;
            public uint dwHighDateTime;
        }
    
        [StructLayout(LayoutKind.Sequential, Pack = 8)]
        public struct tagLARGEINTEGER
        {
            public long QuadPart;
        }
    
        [StructLayout(LayoutKind.Sequential, Pack = 8)]
        public struct tagULARGEINTEGER
        {
            public ulong QuadPart;
        }
    }
    

提交回复
热议问题