近況報告-2016/02/26

【[C#]USB接続デバイス管理の項目を整理中
・各リンクの整理
・名称の整理

2016/02/26

[c#]USB接続デバイス管理 6-有効/無効を切替えるメソッド

前回実装したメソッドを使用して、デバイスの有効/無効を切替えるメソッドにまとめます。

            // デバイスの有効/無効切替時
            public static void SetDeviceEnabled(Guid classGuid, string instanceId, bool enable)
            {
                bool result = false;
                int index = 0;
                DeviceInfoData MyInfoData;
                IntPtr MyIntPtr;
                SafeDeviceInfoSetHandle diSetHandle = null;
                try
                {
                    //デバイスクラスのhandleを取得(classGuidにてシステム内のデバイスから検出)
                    diSetHandle = NativeMethods.SetupDiGetClassDevs(ref classGuid, IntPtr.Zero, IntPtr.Zero, SetupFlag.Present);
                    MyIntPtr = diSetHandle.DangerousGetHandle();
                    //デバイスインフォメーションデータを取得
                    List<DeviceInfoData> List_DeviceInfo = new List<DeviceInfoData>();
                    DeviceInfoData MyDeviceInfo = new DeviceInfoData();
                    MyDeviceInfo.Size = Marshal.SizeOf(MyDeviceInfo);
                    while (NativeMethods.SetupDiEnumDeviceInfo(MyIntPtr, index, ref MyDeviceInfo))
                    {
                        List_DeviceInfo.Add(MyDeviceInfo);
                        MyDeviceInfo = new DeviceInfoData();
                        MyDeviceInfo.Size = Marshal.SizeOf(MyDeviceInfo);
                        index += 1;
                    }

                    DeviceInfoData[] _Array_DeviceInfo = List_DeviceInfo.ToArray();
                    List_DeviceInfo = null;
                    index = 0;
                    const int ERROR_BUFFER = 122;
                    for (int i = 0; i <= _Array_DeviceInfo.Length - 1; i++)
                    {
                        StringBuilder sb = new StringBuilder(1);
                        int requiredSize = 0;                        
                        MyInfoData = _Array_DeviceInfo[i];
                        MyIntPtr = diSetHandle.DangerousGetHandle();
                        result = NativeMethods.SetupDiGetDeviceInstanceId(MyIntPtr, ref MyInfoData, sb, sb.Capacity, out requiredSize);
                        if (result == false && Marshal.GetLastWin32Error() == ERROR_BUFFER)
                        {
                            sb.Capacity = requiredSize;
                            result = NativeMethods.SetupDiGetDeviceInstanceId(MyIntPtr, ref MyInfoData, sb, sb.Capacity, out requiredSize);
                        }

                        if (instanceId.Equals(sb.ToString()))
                        {
                            PropertyParameters _Params = new PropertyParameters();
                            _Params.Size = 8;
                            _Params.MyFunction = Function.PropertyChange;
                            _Params.Scope = Scope.Global;
                            if (enable)
                            { _Params.StateChange = StatusAction.Enable; }
                            else
                            { _Params.StateChange = StatusAction.Disable; }

                            result = NativeMethods.SetupDiSetClassInstallParams(MyIntPtr, ref MyInfoData, ref _Params, Marshal.SizeOf(_Params));
                            //パラメータをデバイスに適用
                            result = NativeMethods.SetupDiChangeState(MyIntPtr, ref MyInfoData);
                            break;
                }  }  }
                finally
                {
                    if (diSetHandle != null)
                    {
                        if (diSetHandle.IsClosed == false)
                        { diSetHandle.Close(); }
                        diSetHandle.Dispose();
            }   }   }

エラー処理等の問題はありますが、状態検知のメソッドと組み合わせて自動で目的のデバイスの有効/無効を切替えれます。
(管理人環境下では、USB端子の管理等を行っています。)

※PC環境
Window 7 Professional SP1/64bit

質問、御指摘等御座いましたら、御遠慮なく御願い致します。

※留意点
・64bitとして動作するとエラーが発生する為、ビルドする際は32bitビルドを行う。
・本コード類は十分なデバックなどを行っていない為、使用する際は各自責任にて行って下さい。

【各ページへのリンク】

[c#]USB接続デバイス管理 5-『setupapi.dll』メソッド実装

構造体の定義付を行ったので『setupapi.dll』のメソッドを実装します。

        // 読込dll
        private const string setupapi = "setupapi.dll";
        ※念のため[C:\\Windows\\System32\\setupapi.dll]を値として使用した方が良いかも知れません。
        //外部dllメソッド
        [DllImport(setupapi, CallingConvention = CallingConvention.Winapi, SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool SetupDiCallClassInstaller(Function function, IntPtr deviceIntPtr, ref DeviceInfoData deviceInfo);

        [DllImport(setupapi, CallingConvention = CallingConvention.Winapi, SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool SetupDiEnumDeviceInfo(IntPtr deviceIntPtr, int index, ref DeviceInfoData deviceInfo);

        [DllImport(setupapi, CallingConvention = CallingConvention.Winapi, CharSet = CharSet.Unicode, SetLastError = true)]
        public static extern SafeDeviceInfoSetHandle SetupDiGetClassDevs(ref Guid guid, IntPtr enumerator, IntPtr parent, SetupFlag flag);

        [DllImport(setupapi, SetLastError = true, CharSet = CharSet.Auto)]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool SetupDiGetDeviceInstanceId(IntPtr deviceIntPtr, ref DeviceInfoData deviceInfo, StringBuilder InstanceId, int IdSize, out int RequiredSize);

        [SuppressUnmanagedCodeSecurity()]
        [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
        [DllImport(setupapi, CallingConvention = CallingConvention.Winapi, SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool SetupDiDestroyDeviceInfoList(IntPtr deviceInfoSet);

        [DllImport(setupapi, CallingConvention = CallingConvention.Winapi, SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool SetupDiSetClassInstallParams(IntPtr deviceIntPtr, ref DeviceInfoData deviceInfo, ref PropertyParameters InstallParams, int ParamsSize);

        [DllImport(setupapi, CallingConvention = CallingConvention.Winapi, SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool SetupDiChangeState(IntPtr deviceIntPtr, [In()]ref DeviceInfoData deviceInfo);

【各ページへのリンク】