C# 进程间通信

2021/12/29 7:11:39

本文主要是介绍C# 进程间通信,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

C# 进程间通信方式

1、main函数传参

(1)、传递参数

Process process = new Process();//创建进程对象
string dependAssemblies = "";
foreach (var depassembly in DependAssemblies.Values)
{
    if (dependAssemblies.Length == 0)
        dependAssemblies = depassembly.Location;
    else
        dependAssemblies = dependAssemblies + "^" + depassembly.Location;
}
ProcessStartInfo startInfo = new ProcessStartInfo("Test.exe", dependAssemblies); // 括号里是(程序名,参数)
startInfo.WorkingDirectory = BasePath;
startInfo.UseShellExecute = true;
process.StartInfo = startInfo;
process.EnableRaisingEvents = true;
process.Exited += Process_Exited;
process.Start();
process.WaitForExit();

(2)、接收参数

public static void Main(string[] args)

args

2、管道通信

(1) 、服务器端代码

 private static void WaitData()
    {
        using (NamedPipeServerStream pipeServer =
        new NamedPipeServerStream("testpipe", PipeDirection.InOut, 1))
        {
            try
            {
                pipeServer.WaitForConnection();
                pipeServer.ReadMode = PipeTransmissionMode.Byte;
                using (StreamReader sr = new StreamReader(pipeServer))
                {
                    string con = sr.ReadToEnd();
                    Console.WriteLine(con);
                }
            }
            catch (IOException e)
            {
                throw e;
            }
        }
    }

(2)、客户端代码

    private static void SendData()
    {
        try
        {
            using (NamedPipeClientStream pipeClient =
          new NamedPipeClientStream("localhost", "testpipe", PipeDirection.InOut, PipeOptions.None, TokenImpersonationLevel.None))
            {
                pipeClient.Connect();
                using (StreamWriter sw = new StreamWriter(pipeClient))
                {
                    sw.WriteLine("hahha");
                    sw.Flush();
                }
            }
        }
        catch (Exception ex)
        {
            throw ex;
        }
       
    }

3、内存共享

    public class ShareMem
    {
        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        public static extern IntPtr SendMessage(IntPtr hWnd, int Msg, int wParam, IntPtr lParam);

        [DllImport("Kernel32.dll", CharSet = CharSet.Auto)]
        public static extern IntPtr CreateFileMapping(int hFile, IntPtr lpAttributes, uint flProtect, uint dwMaxSizeHi, uint dwMaxSizeLow, string lpName);

        [DllImport("Kernel32.dll", CharSet = CharSet.Auto)]
        public static extern IntPtr OpenFileMapping(int dwDesiredAccess, [MarshalAs(UnmanagedType.Bool)] bool bInheritHandle, string lpName);

        [DllImport("Kernel32.dll", CharSet = CharSet.Auto)]
        public static extern IntPtr MapViewOfFile(IntPtr hFileMapping, uint dwDesiredAccess, uint dwFileOffsetHigh, uint dwFileOffsetLow, uint dwNumberOfBytesToMap);

        [DllImport("Kernel32.dll", CharSet = CharSet.Auto)]
        public static extern bool UnmapViewOfFile(IntPtr pvBaseAddress);

        [DllImport("Kernel32.dll", CharSet = CharSet.Auto)]
        public static extern bool CloseHandle(IntPtr handle);

        [DllImport("kernel32", EntryPoint = "GetLastError")]
        public static extern int GetLastError();

        const int ERROR_ALREADY_EXISTS = 183;

        const int FILE_MAP_COPY = 0x0001;
        const int FILE_MAP_WRITE = 0x0002;
        const int FILE_MAP_READ = 0x0004;
        const int FILE_MAP_ALL_ACCESS = 0x0002 | 0x0004;

        const int PAGE_READONLY = 0x02;
        const int PAGE_READWRITE = 0x04;
        const int PAGE_WRITECOPY = 0x08;
        const int PAGE_EXECUTE = 0x10;
        const int PAGE_EXECUTE_READ = 0x20;
        const int PAGE_EXECUTE_READWRITE = 0x40;

        const int SEC_COMMIT = 0x8000000;
        const int SEC_IMAGE = 0x1000000;
        const int SEC_NOCACHE = 0x10000000;
        const int SEC_RESERVE = 0x4000000;

        const int INVALID_HANDLE_VALUE = -1;

        IntPtr m_hSharedMemoryFile = IntPtr.Zero;
        IntPtr m_pwData = IntPtr.Zero;
        IntPtr m_pwDataWrite = IntPtr.Zero;
        IntPtr m_pwDataRead = IntPtr.Zero;
        bool m_bAlreadyExist = false;
        bool m_bInit = false;
        long m_MemSize = 0;
        int m_length = 0;
        int m_count = 0;
        const int infoSize = 50;
        Semaphore semRead;
        Semaphore semWrite;
        Semaphore semWriteLength;
        String m_pathMSGCSV = "Messages.csv";

        public ShareMem()
        {
        }
        ~ShareMem()
        {
            Close();
        }

        ///
        /// 初始化共享内存
        ///
        /// 共享内存名称
        /// 共享内存大小
        ///
        public int Init(string strName, long lngSize)
        {
            if (lngSize <= 0 || lngSize > 0x00800000) lngSize = 0x00800000;
            m_MemSize = lngSize;
            if (strName.Length > 0)
            {
                //创建内存共享体(INVALID_HANDLE_VALUE)
                m_hSharedMemoryFile = CreateFileMapping(INVALID_HANDLE_VALUE, IntPtr.Zero, (uint)PAGE_READWRITE, 0, (uint)lngSize, strName);

                if (GetLastError() == ERROR_ALREADY_EXISTS) //已经创建
                {
                    m_bAlreadyExist = true;
                    m_hSharedMemoryFile = OpenFileMapping(FILE_MAP_ALL_ACCESS, false, strName);
                }

                if (m_hSharedMemoryFile == IntPtr.Zero)
                {
                    m_bAlreadyExist = false;
                    m_bInit = false;
                    return 2; //创建共享体失败
                }
                else
                {
                    if (GetLastError() == ERROR_ALREADY_EXISTS) //已经创建
                    {
                        m_bAlreadyExist = true;
                    }
                    else                                         //新创建
                    {
                        m_bAlreadyExist = false;
                    }
                }
                //---------------------------------------
                //创建内存映射
                m_pwData = MapViewOfFile(m_hSharedMemoryFile, FILE_MAP_ALL_ACCESS, 0, 0, (uint)lngSize);
                m_pwDataWrite = m_pwData;
                m_pwDataRead = (IntPtr)(m_pwData.GetHashCode() + infoSize);
                if (m_pwData == IntPtr.Zero)
                {
                    m_bInit = false;
                    CloseHandle(m_hSharedMemoryFile);
                    return 3; //创建内存映射失败
                }
                else
                {
                    m_bInit = true;
                    if (m_bAlreadyExist == false)
                    {
                        //初始化
                    }
                }
                //----------------------------------------
            }
            else
            {
                return 1; //参数错误    
            }

            SetSemaphore();
            //if (m_bAlreadyExist == false)
            //{
            //    WriteLengthAndCount(0, 0);
            //}
            return 0;     //创建成功
        }

        ///
        /// 关闭共享内存
        ///
        public void Close()
        {
            if (m_bInit)
            {
                UnmapViewOfFile(m_pwData);
                CloseHandle(m_hSharedMemoryFile);
            }
        }

        public bool SetSemaphore()
        {
            try
            {
                semRead = Semaphore.OpenExisting("ReadShareMemory");
                semWrite = Semaphore.OpenExisting("WriteShareMemory");
                semWriteLength = Semaphore.OpenExisting("WriteLengthShareMemory");
            }
            catch (Exception)
            {
                semRead = new Semaphore(0, 1, "ReadShareMemory");
                semWrite = new Semaphore(1, 1, "WriteShareMemory");
                semWriteLength = new Semaphore(1, 1, "WriteLengthShareMemory");
            }
            return true;
        }


        public int ReadLength()
        {
            Byte[] bytData = new Byte[infoSize];
            if (infoSize > m_MemSize) return 2; //超出数据区
            if (m_bInit)
            {
                Marshal.Copy(m_pwData, bytData, 0, infoSize);
            }
            else
            {
                return 1; //共享内存未初始化
            }
            String str = System.Text.Encoding.Unicode.GetString(bytData).Trim('\0');
            m_length = System.Convert.ToInt32(str);
            return 0;     //读成功
        }

        public int WriteLength(int length)
        {
            semWriteLength.WaitOne();
            if (infoSize > m_MemSize) return 2; //超出数据区
            String strLength = System.Convert.ToString(length);
            Byte[] bytData = System.Text.Encoding.Unicode.GetBytes(strLength);
            if (m_bInit)
            {
                Marshal.Copy(bytData, 0, m_pwData, bytData.Length);
            }
            else
            {
                semWriteLength.Release();
                return 1; //共享内存未初始化
            }
            semWriteLength.Release();
            return 0;
        }

        public int Read(ref byte[] bytData, int lngAddr, int lngSize)
        {
            if (lngAddr + lngSize > m_MemSize) return 2; //超出数据区

            if (m_bInit)
            {
                Marshal.Copy(m_pwData, bytData, lngAddr, lngSize);
            }
            else
            {
                return 1;
            }
            return 0;

        }
        //将数据写入共享内存中
        public int Write(byte[] bytData, int lngAddr, int lngSize)
        {
            if (lngAddr + lngSize > m_MemSize) return 2; //超出数据区
            if (m_bInit)
            {
                Marshal.Copy(bytData, lngAddr, m_pwData, lngSize);
            }
            else
            {
                return 1;
            }
            return 0;

        }

    }

4、win32消息

(1)、发送端

public const int WM_COPYDATA = 0x004A;

[DllImport("User32.dll", EntryPoint = "FindWindow")]
public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

/// <summary>
/// 定义用户要传递的消息的数据
/// </summary>
[StructLayout(LayoutKind.Sequential)]
public struct CopyDataStruct
{
    public IntPtr dwData;
    public int cbData;//字符串长度
    [MarshalAs(UnmanagedType.LPStr)]
    public string lpData;//字符串
}

[DllImport("User32.dll", EntryPoint = "SendMessage")]
private static extern int SendMessage(
    IntPtr hWnd,                   //目标窗体句柄
    int Msg,                       //WM_COPYDATA
    int wParam,                //自定义数值
    ref  CopyDataStruct lParam             //结构体
);

/// <summary>
/// 发送消息
/// </summary>
/// <param name="windowName">window的title,建议加上GUID,不会重复</param>
/// <param name="strMsg">要发送的字符串</param>
public static void SendMessage(string windowName, string strMsg)
{
    if (strMsg == null) return;
    IntPtr hwnd = FindWindow(null, windowName);
    if (hwnd != IntPtr.Zero)
    {
        CopyDataStruct cds;
        cds.dwData = IntPtr.Zero;
        cds.lpData = strMsg;
        //注意:长度为字节数
        cds.cbData = System.Text.Encoding.Default.GetBytes(strMsg).Length + 1;
        // 消息来源窗体
        int fromWindowHandler = 0;
        SendMessage(hwnd, WM_COPYDATA, fromWindowHandler, ref  cds);
    }
}

(2)、接收端

public partial class MainWindow : Window
{
        public const int WM_COPYDATA = 0x004A;
        public MainWindow()
        {
            InitializeComponent();
            Loaded += new RoutedEventHandler(MainWindow_Loaded);
        }

        private void MainWindow_Loaded(object sender, RoutedEventArgs e)
        {
            ChangeWindowMessageFilter(WM_COPYDATA, 1);
        }

        [DllImport("user32")]
        public static extern bool ChangeWindowMessageFilter(uint msg, int flags);

        [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 == WM_COPYDATA)
            {
                CopyDataStruct cds = (CopyDataStruct)System.Runtime.InteropServices.Marshal.PtrToStructure(lParam, typeof(CopyDataStruct));
                MessageBox.Show(cds.lpData);
            }
            return hwnd;
        }

        protected override void OnSourceInitialized(EventArgs e)
        {
            base.OnSourceInitialized(e);
            HwndSource hwndSource = PresentationSource.FromVisual(this) as HwndSource;
            if (hwndSource != null)
            {
                IntPtr handle = hwndSource.Handle;
                hwndSource.AddHook(new HwndSourceHook(WndProc));
            }
        }
}

5、C# Hook

// 安装钩子
[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
public static extern int SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hInstance, int threadId);
// 卸载钩子
[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
public static extern bool UnhookWindowsHookEx(int idHook);
// 继续下一个钩子
[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
public static extern int CallNextHookEx(int idHook, int nCode, Int32 wParam, IntPtr lParam);

// 取得当前线程编号
[DllImport("kernel32.dll")]
static extern int GetCurrentThreadId();
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Runtime.InteropServices;
using System.Windows.Forms;

namespace HookWndProc
{
    public partial class Form1 : Form
    {
        // 安装钩子
        [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
        public static extern int SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hInstance, int threadId);
        // 卸载钩子
        [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
        public static extern bool UnhookWindowsHookEx(int idHook);
        // 继续下一个钩子
        [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
        public static extern int CallNextHookEx(int idHook, int nCode, Int32 wParam, IntPtr lParam);

        // 取得当前线程编号
        [DllImport("kernel32.dll")]
        static extern int GetCurrentThreadId();

        public delegate int HookProc(int nCode, Int32 wParam, IntPtr lParam);


        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            HookStart();
        }

        private int KeyboardHookProc(int nCode, Int32 wParam, IntPtr lParam)
        {

            if (nCode >= 0 && wParam == WM_KEYDOWN)
            {
                int vkCode = Marshal.ReadInt32(lParam);  //按键ascii码

                if (vkCode.ToString() == "13")
                {
                    Console.WriteLine("按了Enter");
                }

                //返回1 相当于屏蔽了Enter
                return 1;
            }


            return CallNextHookEx(hKeyboardHook, nCode, wParam, lParam);
        }


        private int MouseHookProc(int nCode, Int32 wParam, IntPtr lParam)
        {
            if (nCode >= 0)
            {
                switch (wParam)
                {
                    case WM_LBUTTONDOWN:
                        Console.WriteLine("鼠标左键按下");
                        break;
                    case WM_LBUTTONUP:
                        Console.WriteLine("鼠标左键抬起");
                        break;
                    case WM_LBUTTONDBLCLK:
                        Console.WriteLine("鼠标左键双击");
                        break;
                    case WM_RBUTTONDOWN:
                        Console.WriteLine("鼠标右键按下");
                        break;
                    case WM_RBUTTONUP:
                        Console.WriteLine("鼠标右键抬起");
                        break;
                    case WM_RBUTTONDBLCLK:
                        Console.WriteLine("鼠标右键双击");
                        break;
                }
            }

            return CallNextHookEx(hMouseHook, nCode, wParam, lParam);

        }


        static int hMouseHook = 0;
        HookProc MouseHookProcedure;

        static int hKeyboardHook = 0;
        HookProc KeyboardHookProcedure;       

        // 安装钩子
        public void HookStart()
        {
            IntPtr hInstance = LoadLibrary("User32");

            if (hKeyboardHook == 0)
            {
                // 创建HookProc实例
                KeyboardHookProcedure = new HookProc(KeyboardHookProc);

                // 设置钩子
                hKeyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL, KeyboardHookProcedure, hInstance, 0);

                // 如果设置钩子失败
                if (hKeyboardHook == 0)
                {
                    HookStop();
                    throw new Exception("SetWindowsHookEx failed.");
                }
            }

            if (hMouseHook == 0)
            {
                MouseHookProcedure = new HookProc(MouseHookProc);
                hMouseHook = SetWindowsHookEx(WH_MOUSE_LL, MouseHookProcedure, hInstance, 0);

                // 如果设置钩子失败
                if (hMouseHook == 0)
                {
                    HookStop();
                    throw new Exception("SetWindowsHookEx failed.");
                }
            }
        }


        // 卸载钩子
        public void HookStop()
        {
            bool retKeyboard = true;

            bool retMouse = true;

            if (hKeyboardHook != 0)
            {
                retKeyboard = UnhookWindowsHookEx(hKeyboardHook);
                hKeyboardHook = 0;
            }

            if (hMouseHook != 0)
            {
                retMouse = UnhookWindowsHookEx(hMouseHook);
                hMouseHook = 0;
            }


            if (!(retMouse && retKeyboard)) throw new Exception("UnhookWindowsHookEx failed.");
        }

       

        #region 钩子类型的枚举
        public const int WH_JOURNALRECORD = 0;      //监视和记录输入事件。安装一个挂钩处理过程,对寄送至系统消息队列的输入消息进行纪录
        public const int WH_JOURNALPLAYBACK = 1;    //回放用WH_JOURNALRECORD记录事件
        public const int WH_KEYBOARD = 2;           //键盘钩子,键盘触发消息。WM_KEYUP或WM_KEYDOWN消息
        public const int WH_GETMESSAGE = 3;         //发送到窗口的消息。GetMessage或PeekMessage触发
        public const int WH_CALLWNDPROC = 4;        //发送到窗口的消息。由SendMessage触发
        public const int WH_CBT = 5;                //当基于计算机的训练(CBT)事件发生时 
        public const int WH_SYSMSGFILTER = 6;       //同WH_MSGFILTER一样,系统范围的。 
        public const int WH_MOUSE = 7;              //鼠标钩子,查询鼠标事件消息
        public const int WH_HARDWARE = 8;           //非鼠标、键盘消息时
        public const int WH_DEBUG = 9;              //调试钩子,用来给钩子函数除错
        public const int WH_SHELL = 10;             //外壳钩子,当关于WINDOWS外壳事件发生时触发. 
        public const int WH_FOREGROUNDIDLE = 11;    //前台应用程序线程变成空闲时候,钩子激活。
        public const int WH_CALLWNDPROCRET = 12;    //发送到窗口的消息。由SendMessage处理完成返回时触发
        public const int WH_KEYBOARD_LL = 13;       //此挂钩只能在Windows NT中被安装,用来对底层的键盘输入事件进行监视
        public const int WH_MOUSE_LL = 14;          //此挂钩只能在Windows NT中被安装,用来对底层的鼠标输入事件进行监视


        public const int WM_MOUSEMOVE = 0x200;
        public const int WM_LBUTTONDOWN = 0x201;
        public const int WM_RBUTTONDOWN = 0x204;
        public const int WM_MBUTTONDOWN = 0x207;
        public const int WM_LBUTTONUP = 0x202;
        public const int WM_RBUTTONUP = 0x205;
        public const int WM_MBUTTONUP = 0x208;
        public const int WM_LBUTTONDBLCLK = 0x203;
        public const int WM_RBUTTONDBLCLK = 0x206;
        public const int WM_MBUTTONDBLCLK = 0x209;


        public const int WM_KEYDOWN = 256;

        #endregion
        [DllImport("kernel32.dll")]
        static extern IntPtr LoadLibrary(string lpFileName);
    }
}


这篇关于C# 进程间通信的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程