成人欧美一区二区三区的电影,日韩一级一欧美一级国产,国产成人国拍亚洲精品,无码人妻精品一区二区三区毛片,伊人久久无码大香线蕉综合

LOGO OA教程 ERP教程 模切知識交流 PMS教程 CRM教程 開發(fā)文檔 其他文檔  
 
網(wǎng)站管理員

記錄一下 WPF進(jìn)程 SendMessage 發(fā)送窗口消息進(jìn)行進(jìn)程間通信,存在進(jìn)程權(quán)限無法接受消息的問題

freeflydom
2025年10月13日 8:8 本文熱度 595

前言

最近在接手一個同事寫的WPF項目,是使用.NetFramwork 開發(fā)的,使用的進(jìn)程間通信沒有使用我們之前封裝的基于WebSocket的封裝組件的,而是使用Win32的方式:發(fā)送端用的Windows Api:SendMessage ,接受端使用的是 鉤子監(jiān)聽windows 的消息回傳。

相信很多做桌面應(yīng)用的,這種通信應(yīng)該都是很常用,并且見怪不怪的??墒强赡芎芏鄾]有注意到進(jìn)程權(quán)限的情況,這種通信存在有坑,并且這個坑還埋的挺深的。

遇到的問題

由于該WPF的項目的啟動方式存在很多方式,如果桌面點擊的方式(普通權(quán)限的),右鍵管理員啟動的方式(管理員權(quán)限的),開機(jī)自啟的方式(System權(quán)限降權(quán)的方式,普通權(quán)限),OTA之后啟動(管理員權(quán)限),這樣就會出現(xiàn)該進(jìn)程窗口可能啟動后的權(quán)限是不可預(yù)見的,并且用戶是可以隨意的變更用戶權(quán)限去啟動。然而,在一次測試中,做了升級后,啟用了該應(yīng)用,其他跟它通信的進(jìn)程就無法跟該進(jìn)程通信的。很詭異,只要是OTA之后,其他進(jìn)程就無法通信,開機(jī)之后(普通權(quán)限)就可以通信。觀察了日志,又沒有報什么異常。

復(fù)現(xiàn)問題

一、創(chuàng)建一個WPF消息 發(fā)送端

<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="發(fā)送" 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 結(jié)構(gòu)
        [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
            {
                //釋放分配的內(nèi)存,即使發(fā)生異常也不會泄漏資源
                Marshal.FreeHGlobal(cds.lpData);
            }
        }
        #endregion
    }
}

 

二、創(chuàng)建一個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="接收到的數(shù)據(jù):"/>
            <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 結(jié)構(gòu)
        [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 = "";
        }
    }

 

三、結(jié)果

1、倆個都是管理員權(quán)限的,是可以接受到數(shù)據(jù)的

 

2、倆個進(jìn)程都是普通權(quán)限的,是可以接受到數(shù)據(jù)

 3、發(fā)送端是管理員權(quán)限,接收端是 普通權(quán)限,是可以接受到數(shù)據(jù)

 

4、發(fā)送端是普通權(quán)限,接收端是 管理員權(quán)限,是接受不到數(shù)據(jù)

 

 總結(jié):

1、進(jìn)程間通信,最好使用無權(quán)限限制的方案

2、使用ChangeWindowMessageFilterEx 進(jìn)行權(quán)限過濾

轉(zhuǎn)自https://www.cnblogs.com/wuty/p/19137419


該文章在 2025/10/13 8:08:09 編輯過
關(guān)鍵字查詢
相關(guān)文章
正在查詢...
點晴ERP是一款針對中小制造業(yè)的專業(yè)生產(chǎn)管理軟件系統(tǒng),系統(tǒng)成熟度和易用性得到了國內(nèi)大量中小企業(yè)的青睞。
點晴PMS碼頭管理系統(tǒng)主要針對港口碼頭集裝箱與散貨日常運作、調(diào)度、堆場、車隊、財務(wù)費用、相關(guān)報表等業(yè)務(wù)管理,結(jié)合碼頭的業(yè)務(wù)特點,圍繞調(diào)度、堆場作業(yè)而開發(fā)的。集技術(shù)的先進(jìn)性、管理的有效性于一體,是物流碼頭及其他港口類企業(yè)的高效ERP管理信息系統(tǒng)。
點晴WMS倉儲管理系統(tǒng)提供了貨物產(chǎn)品管理,銷售管理,采購管理,倉儲管理,倉庫管理,保質(zhì)期管理,貨位管理,庫位管理,生產(chǎn)管理,WMS管理系統(tǒng),標(biāo)簽打印,條形碼,二維碼管理,批號管理軟件。
點晴免費OA是一款軟件和通用服務(wù)都免費,不限功能、不限時間、不限用戶的免費OA協(xié)同辦公管理系統(tǒng)。
Copyright 2010-2025 ClickSun All Rights Reserved