开源 C# 快速开发(十五)进程--windows消息

《C#为何成为Windows平台开发的不二之选?》 综上所述,C#凭借其出色的性能表现、广泛的适用范围、开放包容的态度以及强大的社区力量,在Windows平台乃至整个软件开发领域内占据了重要位置。而对于每一位渴望掌握这项技能的人来说,只要愿意投入足够的时间和精力,相信不久之后便能在C#的世界里收获满满的成功与喜悦。以上就是关于C#作为Windows平台首选语言的优势分析及实际应用案例介绍。希望通过这篇文章能让更多人认识到C#的独特之处,并激发大家对其产生浓厚兴趣。如果您还有任何疑问或者想要了解更多内容,请随时留言交流! 阅读详情

         文章的目的为了记录使用C# 开发学习的经历。开发流程和要点有些记忆模糊,赶紧记录,防止忘记。

 相关链接:

开源 C# 快速开发(一)基础知识

开源 C# 快速开发(二)基础控件

开源 C# 快速开发(三)复杂控件

开源 C# 快速开发(四)自定义控件--波形图

开源 C# 快速开发(五)自定义控件--仪表盘

开源 C# 快速开发(六)自定义控件--圆环

开源 C# 快速开发(七)通讯--串口

开源 C# 快速开发(八)通讯--Tcp服务器端

开源 C# 快速开发(九)通讯--Tcp客户端

开源 C# 快速开发(十)通讯--http客户端

开源 C# 快速开发(十一)线程

开源 C# 快速开发(十二)进程监控

开源 C# 快速开发(十三)进程--管道通讯

开源 C# 快速开发(十四)进程--内存映射

开源 C# 快速开发(十五)进程--windows消息

开源 C# 快速开发(十六)数据库--sqlserver增删改查

推荐链接:

开源 C# .net mvc 开发(一)WEB搭建_c#部署web程序-优快云博客

开源 C# .net mvc 开发(二)网站快速搭建_c#网站开发-优快云博客

开源 C# .net mvc 开发(三)WEB内外网访问-优快云博客

开源 C# .net mvc 开发(四)工程结构、页面提交以及显示-优快云博客

开源 C# .net mvc 开发(五)常用代码快速开发_c# mvc开发-优快云博客

开源 C# .net mvc 开发(六)发送邮件、定时以及CMD编程-优快云博客

开源 C# .net mvc 开发(七)动态图片、动态表格和json数据生成-优快云博客

开源 C# .net mvc 开发(八)IIS Express轻量化Web服务器的配置和使用-优快云博客

开源 C# .net mvc 开发(九)websocket--服务器与客户端的实时通信-优快云博客

本章节主要内容是:进程间 Windows 消息通信的例子。

目录:

1.源码分析

2.所有源码

3.效果演示

一、源码分析

1. MessageHelper.cs 分析
Windows API 声明
 

[DllImport("user32.dll", SetLastError = true)]
public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);


功能:根据类名或窗口标题查找窗口句柄

参数:

lpClassName:窗口类名,为null时按窗口标题查找

lpWindowName:窗口标题文本

返回值:找到的窗口句柄,未找到返回IntPtr.Zero

[DllImport("user32.dll", SetLastError = true)]
public static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);


功能:向指定窗口发送消息

参数:

hWnd:目标窗口句柄

Msg:消息类型(如WM_COPYDATA)

wParam:附加消息参数

lParam:附加消息参数(通常指向数据结构的指针)

数据结构定义
 

[StructLayout(LayoutKind.Sequential)]
public struct COPYDATASTRUCT
{
    public IntPtr dwData;  // 自定义数据,可用于标识消息类型
    public int cbData;     // 数据长度(字节数)
    public IntPtr lpData;  // 指向实际数据的指针
}


作用:用于WM_COPYDATA消息的数据包装结构

LayoutKind.Sequential:确保字段在内存中按声明顺序排列

核心函数分析
SendMessageToProcess 函数
 

public static bool SendMessageToProcess(string windowName, string message)
{
    // 1. 查找目标窗口
    IntPtr targetWindow = FindWindow(null, windowName);
    
    // 2. 字符串编码和内存分配
    byte[] data = Encoding.Unicode.GetBytes(message);
    IntPtr pData = Marshal.AllocCoTaskMem(data.Length);
    Marshal.Copy(data, 0, pData, data.Length);
    
    // 3. 构建COPYDATASTRUCT
    COPYDATASTRUCT cds = new COPYDATASTRUCT();
    cds.dwData = IntPtr.Zero;      // 不使用自定义标识
    cds.cbData = data.Length;      // 数据长度
    cds.lpData = pData;            // 数据指针
    
    // 4. 结构体序列化到指针
    IntPtr pCds = Marshal.AllocCoTaskMem(Marshal.SizeOf(cds));
    Marshal.StructureToPtr(cds, pCds, false);
    
    // 5. 发送消息
    IntPtr result = SendMessage(targetWindow, WM_COPYDATA, IntPtr.Zero, pCds);
    
    // 6. 资源清理
    Marshal.FreeCoTaskMem(pData);
    Marshal.FreeCoTaskMem(pCds);
    
    return result != IntPtr.Zero;
}


执行流程:

窗口查找 → 2. 数据编码 → 3. 内存分配 → 4. 结构构建 → 5. 消息发送 → 6. 资源清理

SendCustomMessage 函数
 

public static bool SendCustomMessage(string windowName, string message)
{
    // 1. 注册系统唯一消息ID
    uint customMsg = (uint)RegisterWindowMessage("MyCustomMessage");
    
    // 2. 查找目标窗口
    IntPtr targetWindow = FindWindow(null, windowName);
    
    // 3. 字符串内存分配
    IntPtr pData = Marshal.StringToHGlobalUni(message);
    
    // 4. 发送自定义消息
    IntPtr result = SendMessage(targetWindow, customMsg, IntPtr.Zero, pData);
    
    // 5. 资源清理
    Marshal.FreeHGlobal(pData);
    
    return result != IntPtr.Zero;
}


特点:使用RegisterWindowMessage确保消息ID在系统范围内唯一

2. MessageReceiverForm.cs 分析
构造函数
 

public MessageReceiverForm()
{
    InitializeComponent();
    customMessage = (uint)RegisterWindowMessage("MyCustomMessage");
    this.Text = $"消息接收器 - PID: {Process.GetCurrentProcess().Id}";
    UpdateStatus("就绪 - 等待接收消息");
}


注册与发送方相同的自定义消息ID

在窗口标题显示进程ID便于调试

消息处理核心 - WndProc
 

protected override void WndProc(ref Message m)
{
    switch (m.Msg)
    {
        case WM_COPYDATA:
            HandleCopyData(ref m);          // 处理WM_COPYDATA
            break;
        case int msg when customMessage != 0 && msg == customMessage:
            HandleCustomMessage(ref m);     // 处理自定义消息
            break;
        default:
            base.WndProc(ref m);           // 其他消息交给基类处理
            break;
    }
}


消息路由机制:

所有Windows消息都经过此方法

根据消息类型分发给对应的处理器

未处理的消息传递给基类

WM_COPYDATA 消息处理
 

private void HandleCopyData(ref Message m)
{
    // 1. 反序列化COPYDATASTRUCT
    COPYDATASTRUCT cds = (COPYDATASTRUCT)Marshal.PtrToStructure(
        m.LParam, typeof(COPYDATASTRUCT));
    
    // 2. 从指针复制数据到字节数组
    byte[] data = new byte[cds.cbData];
    Marshal.Copy(cds.lpData, data, 0, cds.cbData);
    
    // 3. 字节数组解码为字符串
    string message = Encoding.Unicode.GetString(data);
    
    // 4. UI线程安全更新
    this.Invoke(new Action(() =>
    {
        listBoxMessages.Items.Add($"[WM_COPYDATA] {DateTime.Now:HH:mm:ss}: {message}");
        listBoxMessages.SelectedIndex = listBoxMessages.Items.Count - 1;
        UpdateStatus($"收到 WM_COPYDATA 消息: {message}");
    }));
    
    m.Result = (IntPtr)1;  // 告知发送方处理成功
}


关键点:

Marshal.PtrToStructure:将指针转换为结构体

Marshal.Copy:从非托管内存复制到托管数组

this.Invoke:确保UI操作在正确的线程执行

自定义消息处理
 

private void HandleCustomMessage(ref Message m)
{
    // 直接从指针读取字符串
    string message = Marshal.PtrToStringUni(m.LParam);
    
    this.Invoke(new Action(() =>
    {
        listBoxMessages.Items.Add($"[自定义消息] {DateTime.Now:HH:mm:ss}: {message}");
        listBoxMessages.SelectedIndex = listBoxMessages.Items.Count - 1;
        UpdateStatus($"收到自定义消息: {message}");
    }));
    
    m.Result = (IntPtr)1;
}


简化处理:直接使用Marshal.PtrToStringUni转换字符串

UI交互函数
 

private void btnSendToSender_Click(object sender, EventArgs e)
{
    string message = txtSendMessage.Text.Trim();
    if (!string.IsNullOrEmpty(message))
    {
        // 双向通信:接收方也可以发送消息
        bool success = MessageHelper.SendMessageToProcess("消息发送器", message);
        if (success)
        {
            listBoxMessages.Items.Add($"[发送] {DateTime.Now:HH:mm:ss}: {message}");
            listBoxMessages.SelectedIndex = listBoxMessages.Items.Count - 1;
            UpdateStatus($"已发送消息到发送器: {message}");
        }
    }
}


线程安全的状态更新
 

private void UpdateStatus(string status)
{
    if (lblStatus.InvokeRequired)
    {
        lblStatus.Invoke(new Action<string>(UpdateStatus), status);
    }
    else
    {
        lblStatus.Text = $"{DateTime.Now:HH:mm:ss} - {status}";
    }
}


InvokeRequired机制:

检查调用线程是否是创建控件的线程

如果不是,通过Invoke跨线程安全更新UI

3. MessageSenderForm.cs 分析
消息发送函数
 

private void btnSendCopyData_Click(object sender, EventArgs e)
{
    string message = txtMessage.Text.Trim();
    string receiverWindow = txtReceiverWindow.Text.Trim();
    
    if (!string.IsNullOrEmpty(message) && !string.IsNullOrEmpty(receiverWindow))
    {
        bool success = MessageHelper.SendMessageToProcess(receiverWindow, message);
        if (success)
        {
            // 本地记录发送历史
            listBoxSent.Items.Add($"[WM_COPYDATA] {DateTime.Now:HH:mm:ss}: {message}");
            listBoxSent.SelectedIndex = listBoxSent.Items.Count - 1;
            UpdateStatus($"WM_COPYDATA 消息发送成功: {message}");
        }
    }
}


进程启动功能
 

private void btnStartReceiver_Click(object sender, EventArgs e)
{
    // 构建接收器程序路径
    string receiverPath = System.IO.Path.Combine(
        AppDomain.CurrentDomain.BaseDirectory, 
        "MessageReceiver.exe");
    
    if (System.IO.File.Exists(receiverPath))
    {
        Process.Start(receiverPath);  // 启动外部进程
        UpdateStatus("接收器进程已启动");
    }
}


4. 通信流程总结
WM_COPYDATA 通信流程:

发送方:
1. FindWindow("消息接收器") → 获取窗口句柄
2. Encoding.Unicode.GetBytes() → 字符串转字节数组
3. Marshal.AllocCoTaskMem() → 分配非托管内存
4. Marshal.StructureToPtr() → 结构体序列化
5. SendMessage(WM_COPYDATA) → 发送消息

接收方:
1. WndProc(WM_COPYDATA) → 接收消息
2. Marshal.PtrToStructure() → 反序列化结构体  
3. Marshal.Copy() → 复制数据到托管内存
4. Encoding.Unicode.GetString() → 字节数组转字符串
5. UI更新 → 显示接收到的消息

二、所有源码

项目源码由2部分组成,windowsmessageRecv和windowsmessageSend

windowsmessageRecv中包括MessageHelper.cs和MessageReceiverForm。

windowsmessageSend中包括MessageHelper.cs和MessageSenderForm。

MessageHelper.cs文件源码


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

namespace windowsmessageRecv
{
    public static class MessageHelper
    {
        // Windows API
        [DllImport("user32.dll", SetLastError = true)]
        public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

        [DllImport("user32.dll", SetLastError = true)]
        public static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);

        [DllImport("user32.dll")]
        public static extern int RegisterWindowMessage(string lpString);

        [DllImport("user32.dll")]
        public static extern IntPtr SendMessage(IntPtr hWnd, uint msg, IntPtr wParam, string lParam);

        // 常量
        public const int WM_COPYDATA = 0x004A;
        public const int WM_SETTEXT = 0x000C;

        // COPYDATASTRUCT 结构
        [StructLayout(LayoutKind.Sequential)]
        public struct COPYDATASTRUCT
        {
            public IntPtr dwData;
            public int cbData;
            public IntPtr lpData;
        }

        public static bool SendMessageToProcess(string windowName, string message)
        {
            try
            {
                // 查找接收窗口
                IntPtr targetWindow = FindWindow(null, windowName);

                if (targetWindow == IntPtr.Zero)
                {
                    MessageBox.Show($"未找到目标窗口: {windowName}");
                    return false;
                }

                // 准备数据
                byte[] data = Encoding.Unicode.GetBytes(message);
                IntPtr pData = Marshal.AllocCoTaskMem(data.Length);
                Marshal.Copy(data, 0, pData, data.Length);

                // 创建 COPYDATASTRUCT
                COPYDATASTRUCT cds = new COPYDATASTRUCT();
                cds.dwData = IntPtr.Zero;
                cds.cbData = data.Length;
                cds.lpData = pData;

                IntPtr pCds = Marshal.AllocCoTaskMem(Marshal.SizeOf(cds));
                Marshal.StructureToPtr(cds, pCds, false);

                // 发送消息
                IntPtr result = SendMessage(targetWindow, WM_COPYDATA, IntPtr.Zero, pCds);

                // 清理资源
                Marshal.FreeCoTaskMem(pData);
                Marshal.FreeCoTaskMem(pCds);

                return result != IntPtr.Zero;
            }
            catch (Exception ex)
            {
                MessageBox.Show($"发送消息时出错: {ex.Message}");
                return false;
            }
        }

        public static bool SendCustomMessage(string windowName, string message)
        {
            try
            {
                // 注册自定义消息
                uint customMsg = (uint)RegisterWindowMessage("MyCustomMessage");

                if (customMsg == 0)
                {
                    MessageBox.Show("注册自定义消息失败");
                    return false;
                }

                IntPtr targetWindow = FindWindow(null, windowName);

                if (targetWindow == IntPtr.Zero)
                {
                    MessageBox.Show($"未找到目标窗口: {windowName}");
                    return false;
                }

                // 发送字符串消息
                IntPtr pData = Marshal.StringToHGlobalUni(message);
                IntPtr result = SendMessage(targetWindow, customMsg, IntPtr.Zero, pData);
                Marshal.FreeHGlobal(pData);

                return result != IntPtr.Zero;
            }
            catch (Exception ex)
            {
                MessageBox.Show($"发送自定义消息时出错: {ex.Message}");
                return false;
            }
        }

        public static bool SendTextMessage(string windowName, string message)
        {
            try
            {
                IntPtr targetWindow = FindWindow(null, windowName);

                if (targetWindow == IntPtr.Zero)
                {
                    MessageBox.Show($"未找到目标窗口: {windowName}");
                    return false;
                }

                IntPtr result = SendMessage(targetWindow, WM_SETTEXT, IntPtr.Zero, message);
                return result != IntPtr.Zero;
            }
            catch (Exception ex)
            {
                MessageBox.Show($"发送文本消息时出错: {ex.Message}");
                return false;
            }
        }
    }
}

MessageReceiverForm.cs文件源码

using System;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Text;
using System.Windows.Forms;
using System.Diagnostics;

namespace windowsmessageRecv
{
    public partial class MessageReceiverForm : Form
    {
        // Windows API 常量
        private const int WM_COPYDATA = 0x004A;

        // 注册自定义消息
        [DllImport("user32.dll")]
        private static extern int RegisterWindowMessage(string lpString);

        private uint customMessage;
        private ListBox listBoxMessages;
        private Button btnClear;
        private Button btnStartSender;
        private Label lblStatus;
        private TextBox txtSendMessage;
        private Button btnSendToSender;
        private Process senderProcess;

        public MessageReceiverForm()
        {
            InitializeComponent();

            // 注册自定义消息
            customMessage = (uint)RegisterWindowMessage("MyCustomMessage");

            // 显示当前进程ID,方便调试
            //this.Text = $"消息接收器 - PID: {Process.GetCurrentProcess().Id}";
            this.Text = "消息接收器";
            UpdateStatus("就绪 - 等待接收消息");
        }

        private void InitializeComponent()
        {
            this.listBoxMessages = new ListBox();
            this.btnClear = new Button();
            this.btnStartSender = new Button();
            this.lblStatus = new Label();
            this.txtSendMessage = new TextBox();
            this.btnSendToSender = new Button();
            this.SuspendLayout();

            // listBoxMessages
            this.listBoxMessages.Dock = DockStyle.Top;
            this.listBoxMessages.FormattingEnabled = true;
            this.listBoxMessages.Location = new Point(0, 0);
            this.listBoxMessages.Size = new Size(500, 200);
            this.listBoxMessages.BackColor = Color.LightYellow;

            // lblStatus
            this.lblStatus.Dock = DockStyle.Top;
            this.lblStatus.Location = new Point(0, 200);
            this.lblStatus.Size = new Size(500, 25);
            this.lblStatus.BackColor = Color.LightBlue;
            this.lblStatus.TextAlign = ContentAlignment.MiddleCenter;

            // txtSendMessage
            this.txtSendMessage.Location = new Point(10, 235);
            this.txtSendMessage.Size = new Size(300, 20);
            this.txtSendMessage.Text = "这是来自接收器的回复消息";

            // btnSendToSender
            this.btnSendToSender.Location = new Point(320, 235);
            this.btnSendToSender.Size = new Size(80, 23);
            this.btnSendToSender.Text = "发送回复";
            this.btnSendToSender.Click += new EventHandler(this.btnSendToSender_Click);

            // btnStartSender
            this.btnStartSender.Location = new Point(410, 235);
            this.btnStartSender.Size = new Size(80, 23);
            this.btnStartSender.Text = "启动发送器";
            this.btnStartSender.Click += new EventHandler(this.btnStartSender_Click);

            // btnClear
            this.btnClear.Location = new Point(210, 265);
            this.btnClear.Size = new Size(80, 23);
            this.btnClear.Text = "清空消息";
            this.btnClear.Click += new EventHandler(this.btnClear_Click);

            // MessageReceiverForm
            this.ClientSize = new Size(500, 300);
            this.Controls.Add(this.btnClear);
            this.Controls.Add(this.btnStartSender);
            this.Controls.Add(this.btnSendToSender);
            this.Controls.Add(this.txtSendMessage);
            this.Controls.Add(this.lblStatus);
            this.Controls.Add(this.listBoxMessages);
            this.Text = "消息接收器";
            this.StartPosition = FormStartPosition.CenterScreen;

            this.ResumeLayout(false);
            this.PerformLayout();
        }

        // 重写 WndProc 方法来处理 Windows 消息
        protected override void WndProc(ref Message m)
        {
            switch (m.Msg)
            {
                case WM_COPYDATA:
                    HandleCopyData(ref m);
                    break;

                case int msg when customMessage != 0 && msg == customMessage:
                    HandleCustomMessage(ref m);
                    break;

                default:
                    base.WndProc(ref m);
                    break;
            }
        }

        // 处理 WM_COPYDATA 消息
        private void HandleCopyData(ref Message m)
        {
            try
            {
                // 解析 COPYDATASTRUCT
                COPYDATASTRUCT cds = (COPYDATASTRUCT)Marshal.PtrToStructure(
                    m.LParam, typeof(COPYDATASTRUCT));

                // 读取数据
                byte[] data = new byte[cds.cbData];
                Marshal.Copy(cds.lpData, data, 0, cds.cbData);

                string message = Encoding.Unicode.GetString(data);

                // 在 UI 线程中更新界面
                this.Invoke(new Action(() =>
                {
                    listBoxMessages.Items.Add($"[WM_COPYDATA] {DateTime.Now:HH:mm:ss}: {message}");
                    listBoxMessages.SelectedIndex = listBoxMessages.Items.Count - 1;
                    UpdateStatus($"收到 WM_COPYDATA 消息: {message}");
                }));

                m.Result = (IntPtr)1; // 表示消息处理成功
            }
            catch (Exception ex)
            {
                MessageBox.Show("处理 WM_COPYDATA 消息时出错: " + ex.Message);
                m.Result = IntPtr.Zero;
            }
        }

        // 处理自定义消息
        private void HandleCustomMessage(ref Message m)
        {
            try
            {
                // 读取字符串数据
                string message = Marshal.PtrToStringUni(m.LParam);

                this.Invoke(new Action(() =>
                {
                    listBoxMessages.Items.Add($"[自定义消息] {DateTime.Now:HH:mm:ss}: {message}");
                    listBoxMessages.SelectedIndex = listBoxMessages.Items.Count - 1;
                    UpdateStatus($"收到自定义消息: {message}");
                }));

                m.Result = (IntPtr)1;
            }
            catch (Exception ex)
            {
                MessageBox.Show("处理自定义消息时出错: " + ex.Message);
                m.Result = IntPtr.Zero;
            }
        }

        private void btnClear_Click(object sender, EventArgs e)
        {
            listBoxMessages.Items.Clear();
            UpdateStatus("消息列表已清空");
        }

        private void btnStartSender_Click(object sender, EventArgs e)
        {
            try
            {
                // 启动发送器进程
                string senderPath = System.IO.Path.Combine(
                    AppDomain.CurrentDomain.BaseDirectory,
                    "windowsmessageSend.exe");

                if (System.IO.File.Exists(senderPath))
                {
                    senderProcess = Process.Start(senderPath);
                    UpdateStatus("发送器进程已启动");
                }
                else
                {
                    MessageBox.Show($"找不到发送器程序: {senderPath}\n请先编译 MessageSender 项目。");
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("启动发送器失败: " + ex.Message);
            }
        }

        private void btnSendToSender_Click(object sender, EventArgs e)
        {
            string message = txtSendMessage.Text.Trim();
            if (!string.IsNullOrEmpty(message))
            {
                // 发送消息到发送器窗口
                bool success = MessageHelper.SendMessageToProcess("消息发送器", message);
                if (success)
                {
                    listBoxMessages.Items.Add($"[发送] {DateTime.Now:HH:mm:ss}: {message}");
                    listBoxMessages.SelectedIndex = listBoxMessages.Items.Count - 1;
                    UpdateStatus($"已发送消息到发送器: {message}");
                }
                else
                {
                    UpdateStatus($"发送失败,请确保发送器正在运行");
                }
            }
        }

        private void UpdateStatus(string status)
        {
            if (lblStatus.InvokeRequired)
            {
                lblStatus.Invoke(new Action<string>(UpdateStatus), status);
            }
            else
            {
                lblStatus.Text = $"{DateTime.Now:HH:mm:ss} - {status}";
            }
        }

        // COPYDATASTRUCT 结构定义
        [StructLayout(LayoutKind.Sequential)]
        public struct COPYDATASTRUCT
        {
            public IntPtr dwData;
            public int cbData;
            public IntPtr lpData;
        }
    }

    // 程序入口

}

MessageSenderForm.cs文件源码





using System;
using System.Drawing;
using System.Windows.Forms;
using System.Diagnostics;

namespace windowsmessageSend
{
    public partial class MessageSenderForm : Form
    {
        private TextBox txtMessage;
        private Button btnSendCopyData;
        private Button btnSendCustom;
        private ListBox listBoxSent;
        private Button btnClear;
        private TextBox txtReceiverWindow;
        private Label lblStatus;
        private Button btnStartReceiver;

        public MessageSenderForm()
        {
            InitializeComponent();
            //this.Text = $"消息发送器 - PID: {Process.GetCurrentProcess().Id}";
            this.Text = "消息发送器";
            UpdateStatus("就绪 - 可以发送消息");
        }

        private void InitializeComponent()
        {
            this.txtMessage = new TextBox();
            this.btnSendCopyData = new Button();
            this.btnSendCustom = new Button();
            this.listBoxSent = new ListBox();
            this.btnClear = new Button();
            this.txtReceiverWindow = new TextBox();
            this.lblStatus = new Label();
            this.btnStartReceiver = new Button();
            this.SuspendLayout();

            // txtReceiverWindow
            this.txtReceiverWindow.Location = new Point(10, 10);
            this.txtReceiverWindow.Size = new Size(300, 20);
            this.txtReceiverWindow.Text = "消息接收器";

            // txtMessage
            this.txtMessage.Location = new Point(10, 40);
            this.txtMessage.Size = new Size(300, 20);
            this.txtMessage.Text = "这是一条测试消息";

            // btnSendCopyData
            this.btnSendCopyData.Location = new Point(320, 40);
            this.btnSendCopyData.Size = new Size(100, 23);
            this.btnSendCopyData.Text = "发送 WM_COPYDATA";
            this.btnSendCopyData.Click += new EventHandler(this.btnSendCopyData_Click);

            // btnSendCustom
            this.btnSendCustom.Location = new Point(430, 40);
            this.btnSendCustom.Size = new Size(100, 23);
            this.btnSendCustom.Text = "发送自定义消息";
            this.btnSendCustom.Click += new EventHandler(this.btnSendCustom_Click);

            // btnStartReceiver
            this.btnStartReceiver.Location = new Point(320, 10);
            this.btnStartReceiver.Size = new Size(100, 23);
            this.btnStartReceiver.Text = "启动接收器";
            this.btnStartReceiver.Click += new EventHandler(this.btnStartReceiver_Click);

            // listBoxSent
            this.listBoxSent.Dock = DockStyle.Bottom;
            this.listBoxSent.FormattingEnabled = true;
            this.listBoxSent.Location = new Point(0, 120);
            this.listBoxSent.Size = new Size(550, 150);
            this.listBoxSent.BackColor = Color.LightGreen;

            // lblStatus
            this.lblStatus.Dock = DockStyle.Bottom;
            this.lblStatus.Location = new Point(0, 100);
            this.lblStatus.Size = new Size(550, 20);
            this.lblStatus.BackColor = Color.LightBlue;
            this.lblStatus.TextAlign = ContentAlignment.MiddleCenter;

            // btnClear
            this.btnClear.Location = new Point(230, 70);
            this.btnClear.Size = new Size(80, 23);
            this.btnClear.Text = "清空列表";
            this.btnClear.Click += new EventHandler(this.btnClear_Click);

            // MessageSenderForm
            this.ClientSize = new Size(550, 270);
            this.Controls.Add(this.btnClear);
            this.Controls.Add(this.listBoxSent);
            this.Controls.Add(this.lblStatus);
            this.Controls.Add(this.btnStartReceiver);
            this.Controls.Add(this.btnSendCustom);
            this.Controls.Add(this.btnSendCopyData);
            this.Controls.Add(this.txtMessage);
            this.Controls.Add(this.txtReceiverWindow);
            this.Text = "消息发送器";
            this.StartPosition = FormStartPosition.CenterScreen;

            this.ResumeLayout(false);
            this.PerformLayout();
        }

        private void btnSendCopyData_Click(object sender, EventArgs e)
        {
            string message = txtMessage.Text.Trim();
            string receiverWindow = txtReceiverWindow.Text.Trim();

            if (!string.IsNullOrEmpty(message) && !string.IsNullOrEmpty(receiverWindow))
            {
                try
                {
                    bool success = MessageHelper.SendMessageToProcess(receiverWindow, message);
                    if (success)
                    {
                        listBoxSent.Items.Add($"[WM_COPYDATA] {DateTime.Now:HH:mm:ss}: {message}");
                        listBoxSent.SelectedIndex = listBoxSent.Items.Count - 1;
                        UpdateStatus($"WM_COPYDATA 消息发送成功: {message}");
                    }
                    else
                    {
                        UpdateStatus($"发送失败,请确保接收器正在运行");
                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show($"发送消息失败: {ex.Message}");
                    UpdateStatus($"发送失败: {ex.Message}");
                }
            }
            else
            {
                MessageBox.Show("请输入消息内容和接收窗口标题");
            }
        }

        private void btnSendCustom_Click(object sender, EventArgs e)
        {
            string message = txtMessage.Text.Trim();
            string receiverWindow = txtReceiverWindow.Text.Trim();

            if (!string.IsNullOrEmpty(message) && !string.IsNullOrEmpty(receiverWindow))
            {
                try
                {
                    bool success = MessageHelper.SendCustomMessage(receiverWindow, message);
                    if (success)
                    {
                        listBoxSent.Items.Add($"[自定义消息] {DateTime.Now:HH:mm:ss}: {message}");
                        listBoxSent.SelectedIndex = listBoxSent.Items.Count - 1;
                        UpdateStatus($"自定义消息发送成功: {message}");
                    }
                    else
                    {
                        UpdateStatus($"发送失败,请确保接收器正在运行");
                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show($"发送自定义消息失败: {ex.Message}");
                    UpdateStatus($"发送失败: {ex.Message}");
                }
            }
            else
            {
                MessageBox.Show("请输入消息内容和接收窗口标题");
            }
        }

        private void btnStartReceiver_Click(object sender, EventArgs e)
        {
            try
            {
                // 启动接收器进程
                string receiverPath = System.IO.Path.Combine(
                    AppDomain.CurrentDomain.BaseDirectory,
                    "MessageReceiver.exe");

                if (System.IO.File.Exists(receiverPath))
                {
                    Process.Start(receiverPath);
                    UpdateStatus("接收器进程已启动");
                }
                else
                {
                    MessageBox.Show($"找不到接收器程序: {receiverPath}\n请先编译 MessageReceiver 项目。");
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("启动接收器失败: " + ex.Message);
            }
        }

        private void btnClear_Click(object sender, EventArgs e)
        {
            listBoxSent.Items.Clear();
            UpdateStatus("发送列表已清空");
        }

        private void UpdateStatus(string status)
        {
            if (lblStatus.InvokeRequired)
            {
                lblStatus.Invoke(new Action<string>(UpdateStatus), status);
            }
            else
            {
                lblStatus.Text = $"{DateTime.Now:HH:mm:ss} - {status}";
            }
        }
    }


}




三、效果演示

启动接收器和发送器的exe,发送器中点击发送,接收器收到消息。

开源C#桌面快捷键管理器源代码详解 快捷键是提高桌面应用程序效率的关键组成部分。它们允许用户通过按下一个或多个键来执行程序中的常用操作,从而减少鼠标点击次数,加快工作流程。对于熟练的用户来说,快捷键可以显著提高生产力。在Windows桌面应用程序中,快捷键的实现通常涉及低级API调用和对键盘事件的即时响应。 阅读详情

相关推荐

C# Windows Forms 构建 TIBCO EMS 消息调试客户端

消息中间件是企业集成中解耦系统通信的关键组件,TIBCO EMS 作为工业级 JMS 实现,负责可靠的消息路由与队列管理。在测试环境中,开发者常面临消息投递不可见、队列积压难以追踪的痛点,而命令行工具又难以直观展示消息内容与状态。借助 C# 与 Windows Forms 构建轻量级消息调试客户端,可将连接、发送、接收与队列浏览等核心操作封装为界面按钮,直观展示消息 ID、属性和内容,大幅提升集成调试效率。本文从 JMS 连接模型切入,解析连接参数与生命周期管理,并分享 UI 线程阻塞、DLL 平台不匹配等

weixin_30768881的博客 317

开源 C# 快速开发(十五)进程--windows消息。

自定义消息编号需全局唯一,通常使用// 注册消息### 开源 C# 快速开发(十五):进程与 Windows 消息在 Windows 开发中,进程间通信(IPC)是一个常见需求,而 Windows 消息机制是一种轻量级的实现方式。通过发送自定义消息,不同进程可以共享数据或触发行为。C# 提供了丰富的 API 支持这一功能,以下将详细介绍如何通过 Windows 消息实现进程通信。---### Windows 消息机制基础。

pCH_i6fh的博客 431

COMSOL新手必看:手把手教你搭建锂电池P2D模型(附完整参数设置)

本文为COMSOL新手提供了搭建锂电池P2D仿真模型的详细指南。文章从模型原理入手,逐步讲解软件设置、几何构建、关键参数配置及后处理分析,并探讨了如何将仿真结果与智能电池管理中的SOC、SOH估算相结合,为电池性能分析和BMS算法开发提供实用洞见。

transformer2023的博客 233

开源 C# 快速开发(十七)进程--消息队列MSMQ

本文记录了使用C#开发MSMQ进程间通信的学习经历。主要内容包括:1)MSMQ的基本概念和工作模式(点对点/多播);2)服务器端和客户端的代码实现,涵盖队列创建、消息发送接收、自动回复等功能;3)运行效果演示,展示了服务器和客户端之间的双向通信。文章详细分析了关键代码逻辑,并提供了完整的源码,可作为C#开发MSMQ应用的参考。该技术适用于需要可靠异步通信的场景,如系统集成、工作流处理等。

ajassi2000的博客 1290

从零开始:用这些公开数据集搞定电力AI项目(含鸟巢、绝缘子、负荷预测等33个实战资源)

本文系统梳理了电力AI领域33个精选公开数据集,涵盖目标检测、负荷预测等关键场景,如鸟巢检测、绝缘子缺陷识别等。通过实战案例解析数据预处理、模型选型及性能优化策略,帮助工程师快速构建端到端解决方案,解决电力AI项目中的数据获取与处理难题。

weixin_42522552的博客 216

VConsole动态加载

// 移动端真机调试工具 vconsole import VConsole from "vconsole"; import Vue from "vue"; // 动态使用VConsole if(process.env.NODE_ENV==='production'){ if(process.env.VUE_APP_BASEURL.includes('test')||process.env.VUE_APP_BASEURL.includes('pre')){ Vue.prototype

aliven1的博客 1043

开源 C# 快速开发(十二)进程监控

摘要:本文介绍了一个基于C#.NET 4.0开发的进程监控管理系统。该系统采用三层架构设计,包含主窗体、进程监控用户控件和核心功能类。主要功能包括:实时显示进程列表(PID、名称、内存占用等)、进程详细信息查看、进程启动/终止、命令执行输出等。系统实现了良好的错误处理机制、线程安全操作和用户友好界面,采用定时器自动刷新进程列表,并通过锚点布局实现界面自适应。文章详细分析了各模块的源码实现,包括UI构建、事件处理和核心功能方法,并提供了完整源码和效果演示。

ajassi2000的博客 1351

别再乱改grub.cfg了!手把手教你用GRUB2自定义多系统启动菜单(含UEFI/BIOS双模式配置)

本文详细介绍了如何安全、高效地使用GRUB2自定义多系统启动菜单,涵盖UEFI/BIOS双模式配置。通过避免直接编辑grub.cfg文件,采用正确的配置方法和命令,帮助用户打造稳定且美观的启动环境,特别适合Linux多系统用户和开发者。

weixin_42553471的博客 590

开源 C# 快速开发(十三)进程--管道通讯

本文记录了使用C#开发命名管道通信程序的学习过程,包含服务器端和客户端的完整实现。文章详细分析了命名管道通信的架构设计、核心代码实现和关键技术点,包括双向通信、异步处理、消息完整性和线程安全等。服务器端实现了管道初始化、连接管理和消息监听功能,客户端则包含连接建立、错误处理和消息发送机制。源码部分展示了完整的窗体应用程序代码,涵盖了UI控件、事件处理和资源管理。最后通过效果演示验证了进程间通信功能的实现。该文章是C#网络编程系列教程的一部分,后续还涉及串口、TCP、HTTP等通信方式的开发记录。

ajassi2000的博客 1270

易灵思Trion FPGA实战:5分钟搞定MIPI硬核配置(附Interface Designer避坑指南)

本文详细介绍了易灵思Trion FPGA中MIPI硬核的快速配置方法,通过Interface Designer工具实现从时钟配置到数据收发的全流程实战。特别针对初次接触Trion系列的设计师,提供了六个关键配置陷阱及解决方案,帮助开发者高效完成嵌入式视觉和高速数据传输项目。

eee77的博客 791

基于物联网技术智慧园林绿化养护管理信息平台

近几年来,随着经济不断的发展,城市面积不断的扩大,城市管理中的园林绿化工作也在这种趋势下不断的发生着深刻改变。管养企业是否按制定的管养计划严格执行?绿化事件整改是否及时到位?绿地面积是否在稳步增长?管养的效果如何?如何客观评价管养企业的管养工作?这些都是我们各级管理者需要面对的问题。   智慧园林绿化养护管理信息平台的开发思路以“考核”为核心,整个信息平台体现出“新、快、高、全、享”五个特点。   智慧园林绿化养护管理信息平台的整个开发理念为:依托五大技术手段(全球卫星定位系统技术、地理信...

Cesium的博客QQ2252224326 2459

开源 C# 快速开发(十四)进程--内存映射

本文介绍了使用C#内存映射文件实现进程间通信的技术方案。作者通过服务器端和客户端的双窗体程序演示了共享内存的实现,包括1KB内存区域的创建、初始化、读写操作,以及消息格式设计(前4字节存储数据长度)。关键技术点包括MemoryMappedFile类的使用、线程安全读写、UI线程同步和资源释放。文章提供了完整的源码实现,涵盖共享内存初始化、消息收发、异常处理等核心功能,并附有相关开发系列文章的参考链接,形成了一套完整的C#进程通信解决方案。

ajassi2000的博客 1272

群晖NAS下docker安装MySql

本文将一步一步讲解如何在群晖NAS的docker中启用一个MySQL容器 , 算是初学者对问题解决的一个记录.

qq_46375248的博客 5977

开源 C++ QT Widget 开发(十一)进程间通信--Windows 窗口通信

本文记录了使用C++ QTWidget开发跨进程通信功能的学习过程。通过WM_COPYDATA消息机制实现窗口间数据传输,包含发送端和接收端两个程序。发送端通过FindWindow查找目标窗口并使用SendMessage发送消息,接收端通过nativeEvent处理消息。文中详细分析了代码结构,包括数据准备、消息发送和处理逻辑,并提供了完整的源码实现。该功能基于Windows消息机制,实现了简单的生产者-消费者模型,可用于进程间通信。

ajassi2000的博客 1076

MOS五类漏电流与优化策略

分析了五种主要漏电流机制:1)反偏结泄漏,由PN结热激发和隧

硬核科技 444

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

开源 C# 快速开发(八)通讯--Tcp服务器端

本文记录了使用C#开发TCP服务器工具的学习过程。文章详细分析了基于Windows Forms实现的TCP服务器核心代码,包括服务器启动/停止、客户端连接管理、消息收发处理等关键功能。重点介绍了多线程处理、线程安全控制、跨线程UI更新等技术实现,并提供了完整的源码和界面设计说明。该工具实现了TCP服务器的基本功能,支持多客户端连接、数据收发和状态监控,可作为网络通信开发的参考示例。

ajassi2000的博客 1273

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

开源 C# 快速开发(十六)数据库--sqlserver增删改查

本文记录了使用C#开发SQL Server数据库应用的学习过程,主要实现用户表的增删改查功能。文章详细分析了核心代码,包括:1)创建用户表结构;2)实现用户添加、删除、更新和查询功能;3)构建Windows窗体应用界面。代码采用参数化查询防止SQL注入,包含完整的异常处理机制。源码展示了一个完整的用户管理系统,支持用户名模糊搜索、数据绑定和表单验证等功能。文章附带相关开发系列教程链接,适合C#初学者学习数据库操作。

ajassi2000的博客 1463

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

C#快速开发:MSMQ消息队列实战,Spring Boot 启动时将数据库数据预加载到 Redis 缓存。

MSMQ 是 C# 开发中处理进程间通信的强大工具,尤其适合需要可靠性和异步处理的场景。通过命名空间,可以轻松实现队列的创建、消息的发送和接收。对于跨平台需求,可以选择开源消息队列系统作为替代方案。

q5o08hf9的博客 305

C#实战:Windows消息机制全解析,数据结构入门 (五):约束即是力量 —— 深入理解栈。

/ 发送自定义消息// 接收处理。

i4y1dcsp的博客 283

微信HOOk接收消息,发送消息Demo

微信HOOk接收消息,发送消息Demo 【下载地址】微信HOOk接收消息发送消息Demo 这是一个基于微信HOOK技术的Windows版C#开源项目,专为微信自动化管理而设计。通过该Demo,用户可以轻松实现接收消息、自动回复、群消息管理、添加群成员以及无痕清粉等功能。项目详细展示了如何利用HOOK技术对微信进行操作,帮...

gitblog_06797的博客 900

3分钟搞定:Windows微信QQ消息永久保存终极方案

你是否曾因为错过重要消息而懊恼不已?在工作群中,老板的重要通知被撤回;在朋友聊天中,有趣的段子转瞬即逝;在客户沟通中,关键要求消失无踪。RevokeMsgPatcher为你提供了一劳永逸的解决方案——让撤回功能形同虚设,所有消息永久保存。 ## 消息消失的痛点与解决方案 在即时通讯软件中,撤回功能本意是纠正误发消息,但在实际使用中却带来了诸多不便。重要的工作指示、珍贵的聊天记录、关键的业务沟通

gitblog_00274的博客 1094

微信HOOk接收消息发送消息Demo:微信自动化管理的利器

微信HOOk接收消息发送消息Demo:微信自动化管理的利器 【下载地址】微信HOOk接收消息发送消息Demo 这是一个基于微信HOOK技术的Windows版C#开源项目,专为微信自动化管理而设计。通过该Demo,用户可以轻松实现接收消息、自动回复、群消息管理、添加群成员以及无痕清粉等功能。项目详细展示了如何利用HOOK技...

gitblog_06742的博客 1258

CSpy源代码:深入解析Windows应用程序的强大工具

CSpy源代码:深入解析Windows应用程序的强大工具 去发现同类优质开源项目:https://gitcode.com/ 在软件开发领域,了解应用程序的内部运作至关重要。今天,我们将为您介绍一款功能强大的开源工具——C# Spy++源代码。以下是关于这个项目的详细介绍,帮助您更好地理解并使用它。 项目介绍 C# Spy++源代码是一款开源的监视和分析Windows应用程序的工具。Spy++可以帮...

gitblog_06705的博客 662

如何快速上手EasyHook:Windows API钩子的终极配置指南

想要在Windows平台上扩展非托管API功能?EasyHook是你的最佳选择!这个开源项目让你能够使用纯托管代码来拦截和修改Windows API调用,支持32位和64位系统,包括Windows 7到Windows 10的所有版本。无论你是系统开发者还是安全研究员,EasyHook都能为你提供强大的钩子功能。 ## 🚀 环境准备与快速部署 ### 必备工具清单 在开始之前,请确保你的开发环

gitblog_00133的博客 812

C# 编写小巧快速的 Windows 动态桌面软件

开源自己前段时间使用C#编写的Windows动态桌面软件,在接下来的博客我将描写一些技术细节和遇到的一些坑。这个软件可以把视频设置成桌面背景播放,不仅如此而且还可以把网页或一个网页文件设置成桌面背景播放。支持.NETFramework4.7.2和.NETCore两个运行时编译,支持Windows10/11系统(支持Windows8以上系统,手里没有Windows8系统没有测试)。...

biyusr的专栏 1702

百度开源文心5.5 Flash Base:280B MoE 只激活 14B,4 步部署 + 3 个坑,微调还是等指令版

百度开源文心 5.5 Flash 基座权重:280B MoE 每 token 激活 14B,1M 上下文,同尺寸开源 Base 30 项基准多数领先。4 步部署(vLLM/SGLang completions 链路)+ 3 个高频坑 + 动手前 6 点核对清单,并给出微调 Base 还是等指令版的判断线。

weixin_50937681的博客 295
上一篇: 开源 C# 快速开发(十四)进程--内存映射
下一篇: 开源 C# 快速开发(十六)数据库--sqlserver增删改查
ajassi2000
博客等级 码龄22年 2034粉丝 191原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值