C# WPF,通过自定义协议,向其它进程发送参数

注册协议

http://www.cnblogs.com/CodingArt/p/4532465.html

与非托管代码交互操作

如何:实现回调函数

互操作封送处理

IntPtr 结构

利用SendMessage实现winform与wpf之间的消息传递

UnsafeNativeMethods.cs

        /*
         * https://msdn.microsoft.com/zh-cn/library/843s5s5x%28v=vs.100%29.aspx
         * 输出本地计算机上每个窗口的句柄值
         * 使用 EnumWindows 函数来逐步浏览窗口列表,并使用一个托管回调函数(名为 WNDENUMPROC)来输出窗口句柄的值。
         */
        public delegate bool WNDENUMPROC(IntPtr hwnd, uint lParam);
        [DllImport("user32.dll", EntryPoint = "EnumWindows", SetLastError = true)]
        public static extern bool EnumWindows(WNDENUMPROC lpEnumFunc, uint lParam);
        /// <devdoc>http://msdn.microsoft.com/en-us/library/windows/desktop/ms633528(v=vs.85).aspx</devdoc>
        [DllImport("user32", CharSet = CharSet.Auto, ExactSpelling = true)]
        internal static extern bool IsWindow([In] [Optional] IntPtr hWnd);
        /*Retrieves a handle to the specified window‘s parent or owner.*/     [DllImport("user32.dll", EntryPoint = "GetParent", SetLastError = true)]
        public static extern IntPtr GetParent(IntPtr hWnd);
        [DllImport("user32.dll", EntryPoint = "GetWindowThreadProcessId")]
        public static extern uint GetWindowThreadProcessId(IntPtr hWnd, ref uint lpdwProcessId);
        [DllImport("kernel32.dll", EntryPoint = "SetLastError")]
        public static extern void SetLastError(uint dwErrCode);
        private static Hashtable processWnd = new Hashtable();
        private static bool EnumWindowsProc(IntPtr hwnd, uint lParam)
        {
            uint uiPid = 0;

            if (GetParent(hwnd) == IntPtr.Zero)
            {
                GetWindowThreadProcessId(hwnd, ref uiPid);
                if (uiPid == lParam)    // 找到进程对应的主窗口句柄
                {
                    processWnd.Add(uiPid, hwnd);   // 把句柄缓存起来
                    SetLastError(0);    // 设置无错误
                    return false;   // 返回 false 以终止枚举窗口
                }
            }

            return true;
        }
        public static IntPtr GetCurrentWindowHandle(uint proid)
        {
            IntPtr ptrWnd = IntPtr.Zero;
            uint uiPid = proid;
            object objWnd = processWnd[uiPid];

            if (objWnd != null)
            {
                ptrWnd = (IntPtr)objWnd;
                if (ptrWnd != IntPtr.Zero && IsWindow(ptrWnd))  // 从缓存中获取句柄
                {
                    return ptrWnd;
                }
                else
                {
                    ptrWnd = IntPtr.Zero;
                }
            }

            bool bResult = EnumWindows(EnumWindowsProc, uiPid);
            // 枚举窗口返回 false 并且没有错误号时表明获取成功
            if (!bResult && Marshal.GetLastWin32Error() == 0)
            {
                objWnd = processWnd[uiPid];
                if (objWnd != null)
                {
                    ptrWnd = (IntPtr)objWnd;
                }
            }
            return ptrWnd;
        }
    [StructLayout(LayoutKind.Sequential)]
    public struct CopyDataStruct
    {
        public IntPtr dwData;
        public int cbData;//字符串长度
        [MarshalAs(UnmanagedType.LPStr)]
        public string lpData;//字符串
    }

https://msdn.microsoft.com/zh-cn/library/windows/desktop/ms644950%28v=vs.85%29.aspx

Sends the specified message to a window or windows. The SendMessage function calls the window procedure for the specified window and does not return until the window procedure has processed the message.

向窗口发送消息。

IntPtr hWnd

A handle to the window whose window procedure will receive the message.

int msg

The message to be sent.

int wParam

Additional message-specific information.

CopyDataStruct lParam

The return value specifies the result of the message processing; it depends on the message sent.

        [DllImport("user32.dll")]
        public static extern void SendMessage(IntPtr hWnd, int msg, int wParam, ref CopyDataStruct lParam);
    public static class Constants
    {
        public const int WM_COPYDATA = 0x004A;
    }

向指定进程窗口发送消息

        public static void SendMessage(Process process, string msg)
        {
            IntPtr hwnd = UnsafeNativeMethods.GetCurrentWindowHandle((uint)process.Id);
            CopyDataStruct d = new CopyDataStruct();
            d.dwData = IntPtr.Zero;
            d.lpData = msg;
            d.cbData = System.Text.Encoding.Default.GetBytes(msg).Length + 1;
            UnsafeNativeMethods.SendMessage(hwnd, Constants.WM_COPYDATA, 0, ref d);
        }

WPF

MainWindow

Loaded += MainWindow_Loaded;
        void MainWindow_Loaded(object sender, RoutedEventArgs e)
        {
            (PresentationSource.FromVisual(this) as HwndSource).AddHook(new HwndSourceHook(WndProc));
        }
    [StructLayout(LayoutKind.Sequential)]
    public struct CopyDataStruct
    {
        public IntPtr dwData;
        public int cbData;//字符串长度
        [MarshalAs(UnmanagedType.LPStr)]
        public string lpData;//字符串
    }
        IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
        {
            if (msg == Constants.WM_COPYDATA)
            {
                var cds = (CopyDataStruct)Marshal.PtrToStructure(lParam, typeof(CopyDataStruct));
                var cmd = cds.lpData;
                if (oid.IsNotEmpty())
                {
                   ...
                }
            }
            return hwnd;
        }
时间: 2024-10-27 13:03:07

C# WPF,通过自定义协议,向其它进程发送参数的相关文章

mina的编码和解码以及断包的处理,发送自定义协议,仿qq聊天,发送xml或json和

最近一段时间以来,mina很火,和移动开发一样,异常的火爆.前面写了几篇移动开发的文章,都还不错,你们的鼓励就是我最大的动力.好了,废话少说.我们来看下tcp通讯吧. tcp通讯对于java来说是很简单的.就是socket,也就是大家常说的套接字.大家不要把它看的很难.说白了tcp通讯其实就是数据流的读写.一条输入流,一条输出流.分别复杂发消息和接收消息. 明白了这些,ok,我们来看看我写的例子吧.先看服务器端的测试类的源码: package com.minaqq.test; import co

第13章 TCP编程(3)_基于自定义协议的多进程模型

5. 自定义协议编程 (1)自定义协议:MSG //自定义的协议(TLV:Type length Value) typedef struct{ //协议头部 char head[10];//TLV中的T unsigned int checkNum; //校验码 unsigned int cbSizeContent; //协议体的长度 //协议体部 char buff[512]; //数据 }MSG; (2)自定义读写函数 ①extern int write_msg(int sockfd, cha

第13章 TCP编程(4)_基于自定义协议的多线程模型

7. 基于自定义协议的多线程模型 (1)服务端编程 ①主线程负责调用accept与客户端连接 ②当接受客户端连接后,创建子线程来服务客户端,以处理多客户端的并发访问. ③服务端接到的客户端信息后,回显给客户端 (2)客户端编程 ①从键盘输入信息,并发送给服务端 ②接收来自服务端的信息 //msg.h与前一节相同 #ifndef __MSG_H__ #define __MSG_H__ #include <sys/types.h> //求结构体中成员变量的偏移地址 #define OFFSET(T

C#综合揭秘——通过修改注册表建立Windows自定义协议

引言 本文主要介绍注册表的概念与其相关根项的功能,以及浏览器如何通过连接调用自定义协议并与客户端进行数据通信.文中讲及如何通过C#程序.手动修改.安装项目等不同方式对注册表进行修改.其中通过安装项目对注册表进行修改的情况最为常见,在一般的应用程序中都会涉及.当中最为实用的例子将介绍如何通过"安装项目"修改注册表建立自定义协议,在页面通过ajax方式发送路径请求,并在回调函数中调用自定义协议.最后一节还将介绍如何调用自定义协议去保持数据的保密性.希望本篇文章能对各位的学习研究有所帮助,当

【转】C#综合揭秘——通过修改注册表建立Windows自定义协议

引言 本文主要介绍注册表的概念与其相关根项的功能,以及浏览器如何通过连接调用自定义协议并与客户端进行数据通信.文中讲及如何通过C#程序.手动修改.安装项目等不同方式对注册表进行修改.其中通过安装项目对注册表进行修改的情况最为常见,在一般的应用程序中都会涉及.当中最为实用的例子将介绍如何通过"安装项目"修改注册表建立自定义协议,在页面通过ajax方式发送路径请求,并在回调函数中调用自定义协议.最后一节还将介绍如何调用自定义协议去保持数据的保密性.希望本篇文章能对各位的学习研究有所帮助,当

swoole入门教程05-Swoole的自定义协议功能的使用

环境说明: 系统:Ubuntu14.04 (安装教程包括CentOS6.5) PHP版本:PHP-5.5.10 swoole版本:1.7.8-alpha 1.为什么要提供自定义协议 熟悉TCP通信的朋友都会知道,TCP是一个流式协议.客户端向服务器发送的一段数据,可能并不会被服务器一次就完整的收到;客户端向服务器发送的多段数据,可能服务器一次就收到了全部的数据.而实际应用中,我们希望在服务器端能一次接收一段完整的数据,不多也不少.传统的TCP服务器中,往往需要由程序员维护一个缓存区,先将读到的数

WPF 封装 dotnet remoting 调用其他进程

原文:WPF 封装 dotnet remoting 调用其他进程 本文告诉大家一个封装好的库,使用这个库可以快速搭建多进程相互使用. 目录 创建端口 调用软件 运行的类 运行C++程序 通道 使用 在 WPF 使用RPC调用其他进程 已经告诉大家调用的原理,但是大家可以看到,如果自己写一个框架是比较难的. 因为我经常调用 C++ 代码,如果C++出现异常,软件会直接退出,所以我就想把 C++ 代码放在其他进程,这样C++运行出现异常了,软件也不会直接退出. 但是如果每次都需要自己写相同的代码,我

WPF DataGrid自定义样式

WPF DataGrid自定义样式 微软的WPF DataGrid中有很多的属性和样式,你可以调整,以寻找合适的(如果你是一名设计师).下面,找到我的小抄造型的网格.它不是100%全面,但它可以让你走得很远,有一些非常有用的技巧和陷阱. 在DataGrid中的最高水平,你可以改变的外观和感觉,通过设置一些: Property Type Values Default AlternatingRowBackground Brush Any Brush Null Background Brush Any

Netty 5 自定义协议 教程

网上好多连接好多demo都不是netty5的,都是以前的版本,况且还有好多运行时老报错.入门级demo就不写了,估计都是那些老套路.好多公司都会有最佳实践,今天就说说如何自定义协议,一般自定义协议都是公司内部各个部门定义的,当然了我写的比较简单. 注意: 本教程是采用netty-all-5.0.0.Alpha2.jar,netty5的版本,不是网上很多的例子都是采用以前老大版本. 自定义协议: 协议 {   协议头(header)   消息体(body) } header格式 {   固定头,