最近公司有个需求是,拖动文件到桌面图标上,自动打开文件。那么只需在OnStartup事件中通过StartupEventArgs获取文件名然后进行操作即可。操作之后发现当软件已经启动了(单例运行),那么将无法将参数传给业务层。原因是因为跨进程了,那么我们可以通过窗口句柄的方式来进行通讯。

1  public partial classApp : Application2 {3      private staticMutex AppMutex;4      publicApp()5 {6 
7 }8 
9      protected override voidOnStartup(StartupEventArgs e)10 {11          //获取启动参数
12          var param = string.Empty;13          if (e.Args.Length > 0)14 {15              param = e.Args[0].ToString();16 }17 
18          //WpfApp8 = 你的项目名称
19          AppMutex = new Mutex(true, "WpfApp8", out varcreatedNew);20 
21          if (!createdNew)22 {23              var current =Process.GetCurrentProcess();24 
25              foreach (var process inProcess.GetProcessesByName(current.ProcessName))26 {27                  if (process.Id !=current.Id)28 {29 Win32Helper.SetForegroundWindow(process.MainWindowHandle);30 Win32Helper.SendMessageString(process.MainWindowHandle, param);31                      break;32 }33 }34              Environment.Exit(0);35 }36          else
37 {38              base.OnStartup(e);39 }40 }41  }
1  public classWin32Helper2 {3      [DllImport("user32.dll", ExactSpelling = true, CharSet =CharSet.Auto)]4      public static extern boolSetForegroundWindow(IntPtr hWnd);5 
6      /// <summary>
7      ///发送消息8      /// </summary>
9      /// <param name="hWnd"></param>
10      /// <param name="Msg"></param>
11      /// <param name="wParam"></param>
12      /// <param name="lParam"></param>
13      /// <returns></returns>
14      [DllImport("user32.dll")]15      public static extern IntPtr SendMessage(IntPtr hWnd, int Msg, IntPtr wParam, refCOPYDATASTRUCT lParam);16 
17      //声明常量
18      public const int WM_COPYDATA = 0x004A;19 
20      //定义 COPYDATASTRUCT 结构
21 [StructLayout(LayoutKind.Sequential)]22      public structCOPYDATASTRUCT23 {24          publicIntPtr dwData;25          public intcbData;26          publicIntPtr lpData;27 }28 
29      /// <summary>
30      ///发送字符串消息31      /// </summary>
32      /// <param name="hWnd"></param>
33      /// <param name="message"></param>
34      public static void SendMessageString(IntPtr hWnd, stringmessage)35 {36          if (string.IsNullOrEmpty(message)) return;37 
38          byte[] messageBytes = Encoding.Unicode.GetBytes(message + '\0'); //添加终止符
39 
40          COPYDATASTRUCT cds = newCOPYDATASTRUCT();41          cds.dwData =IntPtr.Zero;42          cds.cbData =messageBytes.Length;43          cds.lpData =Marshal.AllocHGlobal(cds.cbData);44          Marshal.Copy(messageBytes, 0, cds.lpData, cds.cbData);45          try
46 {47              SendMessage(hWnd, WM_COPYDATA, IntPtr.Zero, refcds);48 }49          finally
50 {51              //释放分配的内存,即使发生异常也不会泄漏资源
52 Marshal.FreeHGlobal(cds.lpData);53 }54 }55  }
1  public partial classMainWindow : Window2 {3      publicMainWindow()4 {5 InitializeComponent();6 }7 
8      protected override voidOnSourceInitialized(EventArgs e)9 {10          base.OnSourceInitialized(e);11 
12          HwndSource hwndSource = PresentationSource.FromVisual(this) asHwndSource;13 hwndSource.AddHook(WndProc);14 }15 
16      private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref boolhandled)17 {18          if (msg ==WM_COPYDATA)19 {20              COPYDATASTRUCT cds = (COPYDATASTRUCT)Marshal.PtrToStructure(lParam, typeof(COPYDATASTRUCT));21              string receivedMessage =Marshal.PtrToStringUni(cds.lpData);22 
23              Console.WriteLine("收到消息:" +receivedMessage);24 
25              //TODO:业务处理
26 MessageBox.Show(receivedMessage);27 
28              handled = true;29 }30 
31          returnIntPtr.Zero;32 }33  }

标签: none

添加新评论