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);
}
}