在 .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 的相关文章

  • 去除字符串的最佳方法是什么?

    我需要具有最佳性能的想法来删除 过滤字符串 I have string Input view 512 3 159 删除 view 和 的最佳性能方法是什么 和引号 我可以做这个 Input Input Replace view Replac
  • python+win32:检测窗口拖动

    有没有办法检测何时使用 python pywin32 在窗口中拖动不属于我的应用程序的窗口 我想对其进行设置 以便当我拖动标题与桌面边缘附近的图案匹配的窗口时 当松开鼠标时它会捕捉到边缘 我可以编写代码 以便在释放鼠标时将所有具有该标题的窗
  • Visual Studio 2022 - 编译旧应用程序时出错

    我们正在尝试在 Visual Studio 2022 中使用 VB6 32 位应用程序 编译 2002 年以来非常旧的应用程序 我们需要调试此应用程序并能够在 Windows 10 计算机上运行此应用程序 编译时 我们发现以下错误 这似乎是
  • MoveWindow死锁?

    我在线程 A 上有一个窗口 它在某个时刻 由于在其 wndproc 上收到消息 触发线程 B 上的操作 然后等待该操作完成 使用某种同步机制 然后线程B调用MoveWindow 在线程 A 的窗口 例如标准文本框 内移动子窗口 此时程序由于
  • 计算按月分隔的两个日期之间的天数

    我需要计算两个日期之间的天数 DateTime 但有一个转折 我想知道这两天跨越的每个月有多少天 两个人有简单的方法吗 Example 我的开始日期是 30 03 2011 结束日期是 05 04 2011 那么结果应该是这样的 var r
  • MySql 最后插入 ID,连接器 .net

    我正在使用 MySql Connector net 我需要获取最后一个查询生成的插入 id 现在 我假设返回值是MySqlHelper ExecuteNonQuery应该是最后一个插入id 但它只返回1 我正在使用的代码是 int inse
  • 如何将智能感知添加到我的应用程序中?

    我们的一款产品拥有一种专有的宏语言 通过我们的 Windows 软件进行编辑 我想添加智能感知 但我不知道如何去做 至少不完全重新发明轮子 是否有任何示例代码或第 3 方包至少可以让我开始 它不一定是免费的 该应用程序使用 NET 用 C
  • 实用程序库中应包含哪些内容[关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 随着我的项目越来越多 我发现我经常从一个项目到另一个项目 从一个客户到另一个客户重复许多常见的任务 因此 我开始组装一个 实用程序 库 这是这些
  • 如何在 C# 中以编程方式创建柔和的颜色?

    根据所需的颜色数量均匀分布地生成它们 如果指定的计数为 8 则看起来像这样 List
  • 如何在没有 Visual Studio 的情况下将新文件添加到 .csproj 文件

    如何添加新文件到 csproj从命令提示符 我认为没有任何工具可以响应命令行上的 add project 命令来执行此操作 但我认为您可以幸运地创建一个程序 脚本来直接操作 csproj 文件的 XML 内容 csproj 文件的结构如下所
  • EasyNetQ 模型关闭

    我使用 EasyNetQ 实现了一个简单的 RabbitMQ 客户端 连接后 我收到一条通知 队列模型关闭 这是我的代码 var bus RabbitHutch CreateBus String Format host 0 hostName
  • 托管 .NET 代码中的“访问冲突写入位置...”

    我收到以下异常 MqSearch exe 中 0x000007FE21AFE593 mscorlib ni dll 处出现未处理的异常 0xC0000005 写入位置 0x00000006609476FD 时出现访问冲突 代码是完全托管的
  • 如何在 VS2017/2015 中打开 .xproj 文件

    我有一个带有扩展名的 NET core 项目 xproj 当我在VS 2017中打开项目时 项目文件 xproj migrated to csproj 如何打开 xproj 文件 Visual Studio 2017 2015 我需要安装任
  • 如何正确转义mysql?

    我刚刚发现如果我写 select from tbl where name like foo 然后添加 foo 作为参数及其值 a 用户数据 它不会正确转义 我勒个去 它想要 a 即使我使用参数 我还是忍不住觉得我对 sql 注入持开放态度
  • 当我使用 Image.FromFile() 时 FileNotFound

    我在这种情况下使用 Image FromFile string 方法 using System using System Collections Generic using System ComponentModel using Syste
  • c#.NET 和 sprintf 语法

    这段代码如何翻译成 C 具体来说是如何sprintf用C 实现 string output The user s logged in string loggedIn is string loggedOut isn t if TheUser
  • “你好世界!!”在 .NET 4 中生成 3500 个页面错误

    我正在运行 Windows Vista 和 Visual Studio 2010 使用 NET 4 2 GB RAM 和大约 800 MB 可用空间 我创建了一个 Windows 窗体应用程序 但没有向其中添加任何代码 只需在发布模式下编译
  • C# 中的 IPC 机制 - 用法和最佳实践

    不久前我在 Win32 代码中使用了 IPC 临界区 事件和信号量 NET环境下场景如何 是否有任何教程解释所有可用选项以及何时使用以及为什么 微软最近在IPC方面的东西是Windows 通信基础 http en wikipedia org
  • 从 mvc 控制器使用 Web api 控制器操作

    我有两个控制器 一个mvc控制器和一个api控制器 它们都在同一个项目中 HomeController Controller DataController ApiController 如果我想从 HomeController 中使用 Dat
  • 使用 WGL 创建现代 OpenGL 上下文?

    我正在尝试使用 Windows 函数创建 OpenGL 上下文 现代版本 基本上代码就是 创建窗口类 注册班级 创建一个窗口 choose PIXELFORMATDESCRIPTOR并设置它 创建旧版 OpenGL 上下文 使上下文成为当前

随机推荐

  • 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 火线等 出现通知 这