news 2026/7/23 19:16:34

记录一下 WPF进程 SendMessage 发送窗口消息进行进程间通信,存在进程权限无法接受消息的问题

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
记录一下 WPF进程 SendMessage 发送窗口消息进行进程间通信,存在进程权限无法接受消息的问题

前言

最近在接手一个同事写的WPF项目,是使用.NetFramwork 开发的,使用的进程间通信没有使用我们之前封装的基于WebSocket的封装组件的,而是使用Win32的方式:发送端用的Windows Api:SendMessage ,接受端使用的是 钩子监听windows 的消息回传。

相信很多做桌面应用的,这种通信应该都是很常用,并且见怪不怪的。可是可能很多没有注意到进程权限的情况,这种通信存在有坑,并且这个坑还埋的挺深的。

遇到的问题

由于该WPF的项目的启动方式存在很多方式,如果桌面点击的方式(普通权限的),右键管理员启动的方式(管理员权限的),开机自启的方式(System权限降权的方式,普通权限),OTA之后启动(管理员权限),这样就会出现该进程窗口可能启动后的权限是不可预见的,并且用户是可以随意的变更用户权限去启动。然而,在一次测试中,做了升级后,启用了该应用,其他跟它通信的进程就无法跟该进程通信的。很诡异,只要是OTA之后,其他进程就无法通信,开机之后(普通权限)就可以通信。观察了日志,又没有报什么异常。

复现问题

一、创建一个WPF消息 发送端

复制代码

<Window x:Class="FramworkSender.MainWindow"

xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

xmlns:d="http://schemas.microsoft.com/expression/blend/2008"

xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"

xmlns:local="clr-namespace:FramworkSender"

mc:Ignorable="d"

Title="FramworkSender" Height="450" Width="800">

<Grid>

<Button Width="100" Height="100" Content="发送" Click="ButtonBase_OnClick"></Button>

</Grid>

复制代码

复制代码

namespace FramworkSender

{

/// <summary>

/// MainWindow.xaml 的交互逻辑

/// </summary>

public partial class MainWindow : Window

{

public MainWindow()

{

InitializeComponent();

Loaded += MainWindow_Loaded;

}

private void MainWindow_Loaded(object sender, RoutedEventArgs e)

{

}

private void ButtonBase_OnClick(object sender, RoutedEventArgs e)

{

// 获取接收窗口的句柄

IntPtr hwnd = FindWindow(null, "FramworkReceieve");

if (hwnd == IntPtr.Zero)

{

MessageBox.Show("找不到窗口");

}

else

{

SendMessageString(hwnd, "123");

}

}

#region RegisterWindow

[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]

private static extern uint RegisterWindowMessage(string lpString);

private uint _customMessageId;

#endregion

#region CopyData

[DllImport("user32.dll")]

public static extern IntPtr SendMessage(IntPtr hWnd, int Msg, IntPtr wParam, ref COPYDATASTRUCT lParam);

[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]

public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

public const int WM_COPYDATA = 0x004A;

// 定义 COPYDATASTRUCT 结构

[StructLayout(LayoutKind.Sequential)]

public struct COPYDATASTRUCT

{

public IntPtr dwData;

public int cbData;

public IntPtr lpData;

}

public static void SendMessageString(IntPtr hWnd, string message)

{

if (string.IsNullOrEmpty(message)) return;

byte[] messageBytes = Encoding.Unicode.GetBytes(message + '\0');

COPYDATASTRUCT cds = new COPYDATASTRUCT();

cds.dwData = IntPtr.Zero;

cds.cbData = messageBytes.Length;

cds.lpData = Marshal.AllocHGlobal(cds.cbData);

Marshal.Copy(messageBytes, 0, cds.lpData, cds.cbData);

try

{

var result = SendMessage(hWnd, WM_COPYDATA, IntPtr.Zero, ref cds);

}

finally

{

//释放分配的内存,即使发生异常也不会泄漏资源

Marshal.FreeHGlobal(cds.lpData);

}

}

#endregion

}

}

复制代码

二、创建一个WPF 消息 的接收端

复制代码

<Window x:Class="FramworkReceieve.MainWindow"

xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

xmlns:d="http://schemas.microsoft.com/expression/blend/2008"

xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"

xmlns:local="clr-namespace:FramworkReceieve"

mc:Ignorable="d"

Title="FramworkReceieve" Height="450" Width="800">

<Grid>

<StackPanel Orientation="Horizontal">

<TextBlock Text="接收到的数据:"/>

<TextBlock Text="" x:Name="txtMessage"/>

</StackPanel>

<Button Height="100" Width="100" Content="清空" Click="ButtonBase_OnClick"></Button>

</Grid>

</Window>

复制代码

复制代码

/// <summary>

/// MainWindow.xaml 的交互逻辑

/// </summary>

public partial class MainWindow : Window

{

public MainWindow()

{

InitializeComponent();

Loaded += MainWindow_Loaded;

}

private uint _customMessageId;

private HwndSource _hwndSource;

private void MainWindow_Loaded(object sender, RoutedEventArgs e)

{

_customMessageId = RegisterWindowMessage("MyApp");

// 获取窗口句柄并添加消息钩子

_hwndSource = PresentationSource.FromVisual(this) as HwndSource;

_hwndSource?.AddHook(WndProc);

}

[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 16)]

public string content;

private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)

{

#region CopyData

if (msg == WM_COPYDATA)

{

COPYDATASTRUCT cds = (COPYDATASTRUCT)Marshal.PtrToStructure(lParam, typeof(COPYDATASTRUCT));

string receivedMessage = Marshal.PtrToStringUni(cds.lpData);

this.Dispatcher.Invoke(() =>

{

txtMessage.Text = receivedMessage;

});

handled = true;

}

#endregion

return IntPtr.Zero;

}

#region RegisterWindows

[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]

private static extern uint RegisterWindowMessage(string lpString);

#endregion

#region CopyData

public const int WM_COPYDATA = 0x004A;

// 定义 COPYDATASTRUCT 结构

[StructLayout(LayoutKind.Sequential)]

public struct COPYDATASTRUCT

{

public IntPtr dwData;

public int cbData;

public IntPtr lpData;

}

#endregion

protected override void OnClosed(EventArgs e)

{

_hwndSource?.RemoveHook(WndProc);

base.OnClosed(e);

}

private void ButtonBase_OnClick(object sender, RoutedEventArgs e)

{

txtMessage.Text = "";

}

}

复制代码

三、结果

1、俩个都是管理员权限的,是可以接受到数据的

image

2、俩个进程都是普通权限的,是可以接受到数据

image

3、发送端是管理员权限,接收端是 普通权限,是可以接受到数据

image

4、发送端是普通权限,接收端是 管理员权限,是接受不到数据

image

总结:

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/24 4:59:33

【完整源码+数据集+部署教程】动力电池等检测系统源码分享[一条龙教学YOLOV8标注好的数据集一键训练_70+全套改进创新点发刊_Web前端展示]

一、背景意义 随着全球对可再生能源和电动交通工具的日益关注&#xff0c;动力电池的应用范围不断扩大&#xff0c;涵盖了从电动汽车到便携式电子设备等多个领域。动力电池的种类繁多&#xff0c;包括汽车电池、自行车电池、干电池、笔记本电脑电池和智能手机电池等。随着这些电…

作者头像 李华
网站建设 2026/7/21 18:17:56

TDK/INVENSENSE/应美盛传感器ICM-42670-P的概述

ICM-42670-P 是 TDK&#xff08;InvenSense&#xff09;公司生产的一款高性能、低功耗的6轴运动传感器&#xff08;IMU - 惯性测量单元&#xff09;。它集成了一个3轴陀螺仪和一个3轴加速度计于一个紧凑的芯片封装内。ICM-42670-P的核心特性1️⃣. 超低功耗典范◾ 核心优势&…

作者头像 李华
网站建设 2026/7/24 4:35:51

《公共管理学》2025网课答案

文章目录第一章 公共管理的概念及发展--本章习题第二章 政府职能与政府治理--本章习题第三章 公共部门战略管理--本章习题第四章 公共政策的制定与执行--本章习题第五章 公共组织管理--本章习题第六章 公共部门领导--本章习题第七章 公共责任与伦理--本章习题第一章 公共管理的…

作者头像 李华
网站建设 2026/7/23 8:16:50

无需复杂配置!在家也能远程操控 Kali 桌面,cpolar这招太实用了

本文介绍了通过 Xrdp 和 cpolar 实现远程操控 Kali 桌面的方法。首先在 Kali 上安装 Xrdp&#xff0c;更新包管理器后执行安装命令&#xff0c;启用并启动服务&#xff0c;确认 3389 端口开放。本地测试时需退出桌面至锁屏&#xff0c;通过 Windows 远程桌面工具输入局域网 IP …

作者头像 李华
网站建设 2026/7/22 4:40:22

哪吒监控:打造企业级服务器监控体系的5大核心优势

服务器监控是现代IT运维的基石&#xff0c;而哪吒监控&#xff08;Nezha Monitoring&#xff09;作为一款自托管的轻量级解决方案&#xff0c;正在重新定义监控工具的标准。这款工具不仅提供实时性能监控&#xff0c;更通过智能警报和自动化运维功能&#xff0c;帮助运维团队构…

作者头像 李华
网站建设 2026/7/22 3:11:11

终极指南:5分钟快速部署IoTSharp物联网平台

终极指南&#xff1a;5分钟快速部署IoTSharp物联网平台 【免费下载链接】IoTSharp IoTSharp is an open-source IoT platform for data collection, processing, visualization, and device management. 项目地址: https://gitcode.com/gh_mirrors/io/IoTSharp IoTSharp…

作者头像 李华