2

職場では、独自のタブレットを作成しています。一部のタブレットには指紋生体認証がありますが、ないものもあります。技術者がプラグを差し込むのを忘れることがあります。そのデバイス(またはそのことについては何か)が存在するかどうかを確認する方法をまだ見つけていません。

{53D29EF7-377C-4D14-864B-EB3A85769359私の最初のアプローチは、 }である生体認証にGUIDを使用することでした。でレジストリを検索し、hklm\system\currontcontrolset\control\classそのキーが存在するかどうかを確認します。

生体認証をインストールしたことがない場合でも、Windows 7にはそのキーが存在するように見えるため、これは機能しません。XPで動作しましたが、以前は生体認証を備えていたユニットで再試行しましたが、それを取り出したところ、そのキーはまだ存在しています。

この問題の最も難しい部分は、Windows 7、7組み込み、xp、およびxp組み込みで作業する必要があることです。

次のアイデアはWMIを使用することでしたが、WMIが存在するかどうかを確認するために呼び出す正しいクラスが見つかりませんでした。

その後、私は見つけましたbiometric.dllが、それはWindows7でのみ機能します。

問題の一般的な解決策を見つけるのは必ずしも簡単ではない場合があります。私はこのプロジェクトをC#で行っていますが、任意の言語に変換したいと思っています。

私が探し始めるべきだったアイデアはありますか?

4

1 に答える 1

3

私の問題を解決する方法についての素晴らしいリンクを私に与えてくれたJoshuaDrakeの助けを借りて、これらは私の結果です:

私が投稿するように修正しているコードは、特定のGUIDを検索し、最初のGUIDのみを検索するという点で特殊化されています。私はデバイスを無効にする方法についての記事からそれを適応させましたが、このコードは単に存在をチェックするだけでは何も無効にしません。

    public static bool IsDevicePresent(string guid)
    {
        var info = IntPtr.Zero;
        var NullGuid = new Guid(guid);
        try
        {
            info = SetupDiGetClassDevsW(ref NullGuid,null,IntPtr.Zero,DIGCF_PRESENT);
            CheckError("SetupDiGetClassDevs");
            var devdata = new SP_DEVINFO_DATA();
            devdata.cbSize = (UInt32)Marshal.SizeOf(devdata);
            // Get first device matching device criterion.
            SetupDiEnumDeviceInfo(info,0,out devdata);
            // if no items match filter, throw
            if (Marshal.GetLastWin32Error() == ERROR_NO_MORE_ITEMS)
                CheckError("No device found matching filter.", 0xcffff);
            CheckError("SetupDiEnumDeviceInfo");
        }
        catch
        {
            return false;
        }
        finally
        {
            if (info != IntPtr.Zero)
                SetupDiDestroyDeviceInfoList(info);
        }
        return true;
    }

    private static void CheckError(string message, int lasterror = -1)
    {
        int code = lasterror == -1 ? Marshal.GetLastWin32Error() : lasterror;
        if (code != 0)
            throw new ApplicationException(String.Format("Error disabling hardware device (Code {0}): {1}",code, message));
    } 

    [DllImport("setupapi.dll", SetLastError = true)]
    private static extern IntPtr SetupDiGetClassDevsW([In] ref Guid ClassGuid,[MarshalAs(UnmanagedType.LPWStr)]string Enumerator,IntPtr parent,UInt32 flags);

    [DllImport("setupapi.dll", SetLastError = true)]
    private static extern bool SetupDiDestroyDeviceInfoList(IntPtr handle);

    [DllImport("setupapi.dll", SetLastError = true)]
    private static extern bool SetupDiEnumDeviceInfo(IntPtr deviceInfoSet,UInt32 memberIndex,[Out] out SP_DEVINFO_DATA deviceInfoData);  
    //used to find device info from device manager
    [StructLayout(LayoutKind.Sequential)]
    private struct SP_DEVINFO_DATA
    {
        public UInt32 cbSize;
        public Guid classGuid;
        public UInt32 devInst;
        public IntPtr reserved;
    } 
    private const uint DIGCF_PRESENT = 2;
    private const uint ERROR_INVALID_DATA = 13;
    private const uint ERROR_NO_MORE_ITEMS = 259;
    private const uint ERROR_ELEMENT_NOT_FOUND = 1168;

そして、これが最初のデバイスで機能することを証明するための簡単な単体テストです

    [Test]
    public void TestDevicePresent()
    {
        var bluetoothClassGuid = "e0cbf06c-cd8b-4647-bb8a-263b43f0f974";
        var biometricClassGuid = "53D29EF7-377C-4D14-864B-EB3A85769359";
        var cdromdrivClassGiud = "4d36e965-e325-11ce-bfc1-08002be10318";
        Assert.False(Native.IsDevicePresent(bluetoothClassGuid));
        Assert.False(Native.IsDevicePresent(biometricClassGuid));
        Assert.True(Native.IsDevicePresent(cdromdrivClassGiud));
    }
于 2012-05-09T15:09:30.177 に答える