在 .NET 应用程序中使用 RegisterDeviceNotification

2023-12-12

我已经看到了一些有关如何从 Windows API 使用 RegisterDeviceNotification 的示例,但我还没有看到任何 .NET 示例。我想编写一个 C# 应用程序,当新驱动器出现时(特别是通过 USB、火线等)出现通知。这个应用程序需要是一个Windows服务,所以如果没有一些不良的黑客行为,我就无法使用WM_DEVICECHANGE消息。我想避免这种情况。谁能给我一个如何在 C# 中使用 RegisterDeviceNotification 的示例,或者至少给我一个很好的替代方案?

EDIT:再说一遍,这是 Windowsservice没有图形用户界面。所以可能重复涉及 WM 通知消息的内容在这种情况下不起作用。


这个答案提供了检测USB设备移除或添加的相关代码示例:

using System;
using System.Runtime.InteropServices;

internal static class UsbNotification
{
    public const int DbtDevicearrival = 0x8000; // system detected a new device        
    public const int DbtDeviceremovecomplete = 0x8004; // device is gone      
    public const int WmDevicechange = 0x0219; // device change event      
    private const int DbtDevtypDeviceinterface = 5;
    private static readonly Guid GuidDevinterfaceUSBDevice = new Guid("A5DCBF10-6530-11D2-901F-00C04FB951ED"); // USB devices
    private static IntPtr notificationHandle;

    /// <summary>
    /// Registers a window to receive notifications when USB devices are plugged or unplugged.
    /// </summary>
    /// <param name="windowHandle">Handle to the window receiving notifications.</param>
    public static void RegisterUsbDeviceNotification(IntPtr windowHandle)
    {
        DevBroadcastDeviceinterface dbi = new DevBroadcastDeviceinterface
        {
            DeviceType = DbtDevtypDeviceinterface,
            Reserved = 0,
            ClassGuid = GuidDevinterfaceUSBDevice,
            Name = 0
        };

        dbi.Size = Marshal.SizeOf(dbi);
        IntPtr buffer = Marshal.AllocHGlobal(dbi.Size);
        Marshal.StructureToPtr(dbi, buffer, true);

        notificationHandle = RegisterDeviceNotification(windowHandle, buffer, 0);
    }

    /// <summary>
    /// Unregisters the window for USB device notifications
    /// </summary>
    public static void UnregisterUsbDeviceNotification()
    {
        UnregisterDeviceNotification(notificationHandle);
    }

    [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    private static extern IntPtr RegisterDeviceNotification(IntPtr recipient, IntPtr notificationFilter, int flags);

    [DllImport("user32.dll")]
    private static extern bool UnregisterDeviceNotification(IntPtr handle);

    [StructLayout(LayoutKind.Sequential)]
    private struct DevBroadcastDeviceinterface
    {
        internal int Size;
        internal int DeviceType;
        internal int Reserved;
        internal Guid ClassGuid;
        internal short Name;
    }
}

从 WPF 窗口使用:

    protected override void OnSourceInitialized(EventArgs e)
    {
        base.OnSourceInitialized(e);

        // Adds the windows message processing hook and registers USB device add/removal notification.
        HwndSource source = HwndSource.FromHwnd(new WindowInteropHelper(this).Handle);
        if (source != null)
        {
            windowHandle = source.Handle;
            source.AddHook(HwndHandler);
            UsbNotification.RegisterUsbDeviceNotification(windowHandle);
        }
    }

    /// <summary>
    /// Method that receives window messages.
    /// </summary>
    private IntPtr HwndHandler(IntPtr hwnd, int msg, IntPtr wparam, IntPtr lparam, ref bool handled)
    {
        if (msg == UsbNotification.WmDevicechange)
        {
            switch ((int)wparam)
            {
                case UsbNotification.DbtDeviceremovecomplete:
                    Usb_DeviceRemoved(); // this is where you do your magic
                    break;
                case UsbNotification.DbtDevicearrival:
                    Usb_DeviceAdded(); // this is where you do your magic
                    break;
            }
        }

        handled = false;
        return IntPtr.Zero;
    }

Windows 窗体的用法:

public Form1()
{
    InitializeComponent();
    UsbNotification.RegisterUsbDeviceNotification(this.Handle);
}

protected override void WndProc(ref Message m)
{
    base.WndProc(ref m);
        if (m.Msg == UsbNotification.WmDevicechange)
    {
        switch ((int)m.WParam)
        {
            case UsbNotification.DbtDeviceremovecomplete:
                Usb_DeviceRemoved(); // this is where you do your magic
                break;
            case UsbNotification.DbtDevicearrival:
                Usb_DeviceAdded(); // this is where you do your magic
                break;
        }
    }
}    
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在 .NET 应用程序中使用 RegisterDeviceNotification 的相关文章

随机推荐

  • setTimeOut 参数传递

    在 JavaScript 中我想使用setTimeOut 像这样的功能 最好的方法是通过匿名function设置超时 这个匿名函数将能够访问id setTimeout function showGrid id 5000 将字符串传递给set
  • 使用 Objective-C 执行 PHP 脚本

    我正在尝试执行一个 PHP 脚本来增加数据库中的字段 我的脚本正在运行 并且我目前正在使用 ASIHTTPRequest 完美地修改数据库 但我觉得我应该使用不同的方法 因为我不需要返回 这就是所谓的 HTTP POST 吗 increme
  • 批处理文件:迭代自给定日期以来修改的文件

    我想创建一个批处理文件 该文件对与某个日期以来修改的通配符 例如 jpg 匹配的每个文件执行命令 作为一个简单的示例 删除文件 尽管我的命令是自定义 不同的 2010 年 1 月 1 日或之后 该日期可以硬编码在批处理文件中 也可以作为命令
  • 使用 Ajax 实时更改数据库

    我正在建立一个网站 将其Mysql数据库中的内容打印到页面上以供用户查看 数据库的内容将不断添加 我想在页面上实时显示这些更改 而无需用户重新加载 我现在正在使用 PHP 将数据库的内容回显到页面 效果很好 只是要看到任何新的更改 必须重新
  • HTML 通过一个复选框提交多个值?

    您好 我有一个表单 允许用户检查任意数量的选项 然后点击提交 有没有办法让输入类型 复选框 提交多个值 例如现在我有
  • 标记为通过的长时间运行单元测试失败 TFS 构建 - 对象“xxx.rem”已断开连接或服务器上不存在。**

    我想利用 TFS 和 MSTest 进行回归测试 我有一些长时间运行的单元测试 10分钟以上 单元测试可以在 VS2017 内的开发人员机器上本地成功运行 TFS2017 上显示单元测试已通过 然而 构建被标记为失败 对我来说 这个问题看起
  • 是否可以阻止“powershell”以 ANSI 序列包装输出?

    I CreateProcess win32 powershell并从中读取原始字节 我发现它产生了很多看不见的字符 例如 u 1b 2J u 1b m u 1b 有什么办法可以阻止它吗 确实可以手动剥离它们 但我确实希望有其他方法 你提到p
  • 在使用 DOMDocument 函数处理之前修复 PHP 中格式错误的 XML

    我需要将来自外部源的 XML 文档加载到 PHP 中 XML 没有声明它的编码并且包含非法字符 例如 如果我尝试直接在浏览器中加载 XML 文档 我会收到类似 在文本内容中发现无效字符 的错误 并且在 PHP 中加载文件时也会收到很多警告
  • 通过adb shell pm删除domain的包

    有一个命令可以减轻 Android 手机管理包的痛苦 adb shell pm uninstall org kde necessitas example one adb shell pm uninstall org kde necessit
  • 使用 Flutter sqflite 加载 JSON1 扩展

    在我的 Flutter 应用程序中 我使用 sqflite 与本地数据库进行通信 我需要查看 JSON 数据 这JSON1 扩展将是理想的选择 然而 我不能加载扩展在 Flutter 应用程序中 使其在我的查询中可用 因为该文档适用于 C
  • 我的 htaccess RewriteRule 适用于 localhost/mysite,但不适用于 1&1 共享主机上的 mysite.com

    Solved 不幸的是 该解决方案并不令人满意 今天早上 当尝试 Wige 的建议时 令我惊讶的是 我发现预期值实际上已作为GET询问 显然 1 1 我知道他们在过去几周一直在改变他们的环境 在幕后做了一些事情 神奇地解决了我的问题 现在我
  • 删除 XSL 中的双引号

    我正在使用 XSL 1 0 我有这种 XML
  • Tcl 变量大小限制

    我正在写一个Tcl将在嵌入式设备上使用的脚本 该脚本中变量的值将来自系统上的文本文件 我担心的是 如果源文件太大 可能会导致设备崩溃 因为可能没有足够的内存来存储整个文件 我想知道是否可以限制变量的大小 以便在输入变量时不会耗尽全部内存 另
  • 长时间运行的 SELECT 查询的部分结果?

    我们正在 mysql 数据库上发出一些长时间运行的查询 上下文是离线数据分析 而不是应用程序 我们将如何进行研究取决于我们在此过程中获得的结果 能够查看 部分 结果对我们很有用当它们生成时通过 SELECT 语句 在查询完成之前 这可能吗
  • angular-cli:切换到 webpack 后环境文件替换被破坏(使用“ngject”)

    我决定为 angular cli 使用扩展的 webpack 配置 所以我运行了命令ng eject 看起来除了 Angular cli json 中指定的环境文件替换之外 一切都正常 environmentSource environme
  • 如果 wpf 应用程序没有响应,则自动重新启动

    我有一个 WPF 应用程序 偶尔会崩溃 并显示 没有响应 有没有办法检测程序是否没有响应 如果是这样 重新启动 WPF 应用程序 这将是一个临时修复 直到错误修复为止 您可以使用 Windows Vista 中引入的应用程序恢复和重新启动管
  • Angular Material 2 - 在单元测试中触发 md-checkbox 中的更改事件

    我在使用 Angular CLI 提供的测试框架设置触发 Angular 单元测试中 md checkbox 的 更改 事件时遇到问题 我有一个简单的组件 ts import Component from angular core Comp
  • 为什么我的函数代理没有在 Node 中被调用?

    我正在使用代理get方法很好 然后我尝试在一个函数上使用它并很快意识到我需要使用apply方法 这个简单的例子不起作用 它永远不会进入应用程序 Node看起来支持applyhttps node green ES2015 built ins
  • Android:如何使用 ECLIPSE IDE 捕获 LogCat 日志或将日志重定向到文件

    在 Android 中 如何使用 ECLIPSE IDE 捕获 LogCat 日志或将日志重定向到文件 我不想使用命令提示符选项 因为我还没有配置过 谢谢 See 日志猫 安卓开发者 可以从命令提示符重定向到文件 使用adb logcat
  • 在 .NET 应用程序中使用 RegisterDeviceNotification

    我已经看到了一些有关如何从 Windows API 使用 RegisterDeviceNotification 的示例 但我还没有看到任何 NET 示例 我想编写一个 C 应用程序 当新驱动器出现时 特别是通过 USB 火线等 出现通知 这