C#使用SendMessage进行进程间通讯
|
2024年9月23日 8:3
本文热度 1215
|
最近公司有个需求是,拖动文件到桌面图标上,自动打开文件。那么只需在OnStartup事件中通过StartupEventArgs获取文件名然后进行操作即可。操作之后发现当软件已经启动了(单例运行),那么将无法将参数传给业务层。原因是因为跨进程了,那么我们可以通过窗口句柄的方式来进行通讯。
public partial class App : Application
{
private static Mutex AppMutex;
public App()
{
}
protected override void OnStartup(StartupEventArgs e)
{
var param = string.Empty;
if (e.Args.Length > 0)
{
param = e.Args[0].ToString();
}
AppMutex = new Mutex(true, "WpfApp8", out var createdNew);
if (!createdNew)
{
var current = Process.GetCurrentProcess();
foreach (var process in Process.GetProcessesByName(current.ProcessName))
{
if (process.Id != current.Id)
{
Win32Helper.SetForegroundWindow(process.MainWindowHandle);
Win32Helper.SendMessageString(process.MainWindowHandle, param);
break;
}
}
Environment.Exit(0);
}
else
{
base.OnStartup(e);
}
}
}
public class Win32Helper
{
[DllImport("user32.dll", ExactSpelling = true, CharSet = CharSet.Auto)]
public static extern bool SetForegroundWindow(IntPtr hWnd);
[DllImport("user32.dll")]
public static extern IntPtr SendMessage(IntPtr hWnd, int Msg, IntPtr wParam, ref COPYDATASTRUCT lParam);
public const int WM_COPYDATA = 0x004A;
[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
{
SendMessage(hWnd, WM_COPYDATA, IntPtr.Zero, ref cds);
}
finally
{
Marshal.FreeHGlobal(cds.lpData);
}
}
}
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
protected override void OnSourceInitialized(EventArgs e)
{
base.OnSourceInitialized(e);
HwndSource hwndSource = PresentationSource.FromVisual(this) as HwndSource;
hwndSource.AddHook(WndProc);
}
private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
{
if (msg == WM_COPYDATA)
{
COPYDATASTRUCT cds = (COPYDATASTRUCT)Marshal.PtrToStructure(lParam, typeof(COPYDATASTRUCT));
string receivedMessage = Marshal.PtrToStringUni(cds.lpData);
Console.WriteLine("收到消息:" + receivedMessage);
MessageBox.Show(receivedMessage);
handled = true;
}
return IntPtr.Zero;
}
}

转自https://www.cnblogs.com/wihalo/p/18293731
该文章在 2024/9/25 8:35:35 编辑过