WPF 点击图标显示已存在的程序
一.判断进程是否已存在并发送信息
Process current = Process.GetCurrentProcess();
LogUtils.e("进程名称:" + current.ProcessName);
Process[] ps = Process.GetProcessesByName(current.ProcessName);
Console.WriteLine("进程长度:" + ps.Length);
LogUtils.e("程序:" + targetExeName + "=" + productName);
if (ps.Length > 1)
{
//程序已存在
//查找已存在的程序
CallBack myCallBack = new CallBack(FineAppWindow);
EnumWindows(myCallBack, 0);
//发送信息
sendMessage(hWnd, "222");
//关闭当前的程序
Environment.Exit(0);
}
else
{
//启动软件
}
二.获取程序的句柄方法
private static string strProcessName = 当前程序的strProcessName;
static IntPtr hWnd;
public class MessageHelper
{
public const int WM_COPYDATA = 438;
}
public void sendMessage(IntPtr hwnd, string strMsg)
{
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, 438, fromWindowHandler, ref cds);
}
}
[DllImport("User32.dll", EntryPoint = "SendMessage")]
private static extern int SendMessage
(
IntPtr hWnd, //目标窗体句柄
int Msg, //WM_COPYDATA
int wParam, //自定义数值
ref CopyDataStruct lParam //结构体
);
[StructLayout(LayoutKind.Sequential)]
public struct CopyDataStruct
{
public IntPtr dwData;
public int cbData;//字符串长度
[MarshalAs(UnmanagedType.LPStr)]
public string lpData;//字符串
}
[DllImport("user32.dll", EntryPoint = "ShowWindow")]
public static extern int ShowWindow(int hwnd, int nCmdShow);
[DllImport("user32")]
public static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, int nMaxCount);
[DllImport("user32")]
public static extern int EnumWindows(CallBack x, int y);
public delegate bool CallBack(IntPtr hWnd, int lParam);
public static bool FineAppWindow(IntPtr hwnd, int lParam)
{
StringBuilder sb = new StringBuilder(200);
//获取winform的title 与 strProcessName比较
int n = GetWindowText(hwnd, sb, 200);
Console.WriteLine("句柄获取:" + hwnd + "=" + sb.ToString());
if (sb.ToString() == strProcessName)
{
Console.WriteLine("句柄获取成功");
hWnd = hwnd;
}
return true;
}
三.接收数据
-
在Window中添加Initialized监听
this.SourceInitialized += win_SourceInitialized;-
win_SourceInitialized具体实现
private void win_SourceInitialized(object sender, EventArgs e) { HwndSource hwndSource = PresentationSource.FromVisual(this) as HwndSource; if (hwndSource != null) { hwndSource.AddHook(new HwndSourceHook(WndProc)); } }private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled) { switch (msg) { //此处对信息进行区分 case MessageHelper.WM_COPYDATA: //LogUtils.e("启动成功!!"); this.Show(); this.WindowState = WindowState.Normal; break; } return IntPtr.Zero; }
-
该代码段展示了如何在WPF中检查同一进程是否已运行,并通过发送WM_COPYDATA消息与已存在的实例通信。如果程序已运行,它将找到窗口句柄并发送消息,然后关闭当前实例;否则,它会启动新实例。
6987

被折叠的 条评论
为什么被折叠?



