You need to enable JavaScript to run this app. C#调用base.WndProc报错“object不包含WndProc定义”问题求助
优惠活动
大模型
产品
解决方案
定价
更多

C#调用base.WndProc报错“object不包含WndProc定义”问题求助

报错原因

  1. WndProc 是 System.Windows.Forms.Form 类提供的受保护虚方法,你当前的 Program 类默认继承自 object 基类,object 没有定义 WndProc 方法,因此调用 base.WndProc(ref m) 时会直接触发该报错。
  2. 额外的逻辑缺陷:WM_DEVICECHANGE 是Windows系统发送给窗口对象的系统消息,控制台应用默认没有窗口句柄和消息循环,即使解决了语法报错,当前代码也无法接收到USB插拔的通知消息。

修复方案

方案1:WinForm项目实现(推荐)

如果你是做WinForm桌面应用,直接将消息处理逻辑迁移到主窗体类即可:

  • 新建Windows窗体应用项目,将 WndProc 重写方法、DEV_BROADCAST_VOLUME 结构体、DriveMaskToLetter 方法全部复制到主窗体类(默认类名Form1,已默认继承Form)。
  • 无需修改base.WndProc调用,此时base指向Form基类,存在合法的WndProc实现。
  • 程序启动后保持主窗体运行,即可正常接收USB设备插拔通知。

方案2:控制台项目兼容实现

如果需要保留控制台项目形态,可以自定义隐藏窗口类承载消息逻辑,示例代码如下:

using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;

namespace ConsoleApp5
{
    // 自定义隐藏窗口类,继承Form获得WndProc能力
    public class UsbMonitorForm : Form
    {
        const int WM_DEVICECHANGE = 0x0219;
        const int DBT_DEVICEARRIVAL = 0x8000;
        const int DBT_DEVICEREMOVALCOMPLETE = 0x8004;
        const int DBT_DEVTYPVOLUME = 0x00000002;

        protected override void WndProc(ref Message m)
        {
            if (m.Msg == WM_DEVICECHANGE)
            {
                DEV_BROADCAST_VOLUME vol = (DEV_BROADCAST_VOLUME)Marshal.PtrToStructure(m.LParam, typeof(DEV_BROADCAST_VOLUME));
                if ((m.WParam.ToInt32() == DBT_DEVICEARRIVAL) && (vol.dbcv_devicetype == DBT_DEVTYPVOLUME))
                {
                    MessageBox.Show(DriveMaskToLetter(vol.dbcv_unitmask).ToString());
                }
                if ((m.WParam.ToInt32() == DBT_DEVICEREMOVALCOMPLETE) && (vol.dbcv_devicetype == DBT_DEVTYPVOLUME))
                {
                    MessageBox.Show("usb out");
                }
            }
            base.WndProc(ref m);
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct DEV_BROADCAST_VOLUME
        {
            public int dbcv_size;
            public int dbcv_devicetype;
            public int dbcv_reserved;
            public int dbcv_unitmask;
        }

        private static char DriveMaskToLetter(int mask)
        {
            char letter;
            string drives = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
            int cnt = 0;
            int pom = mask / 2;
            while (pom != 0)
            {
                pom = pom / 2;
                cnt++;
            }
            letter = cnt < drives.Length ? drives[cnt] : '?';
            return letter;
        }
    }

    public class Program
    {
        [STAThread]
        static void Main(string[] args)
        {
            // 启动消息循环,运行隐藏窗口
            Application.Run(new UsbMonitorForm() { ShowInTaskbar = false, WindowState = FormWindowState.Minimized });
        }
    }
}

使用该方案需要额外注意:控制台项目需要先添加System.Windows.Forms程序集引用,同时给Main方法加上[STAThread]特性才能正常启动窗体消息循环。

内容的提问来源于stack exchange,提问作者Aishwarya Munuswamy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.21 12:21:04