2012-07-09 123 views
2

我有一个叫做app1的WPF应用程序,它有一个名为window1的窗口。当用户点击关闭按钮window1时,该应用程序不关闭,但窗口1隐藏(this.hide())。从C#中的另一个应用程序显示WPF窗口#

我想检查应用程序的另一个实例是否已经在启动时运行;如果是这样,我想显示已经运行的实例并终止新的实例。

我该怎么做?

我知道如何检查的过程中,如何关闭当前应用程序,但我不知道如何表达从其他正在运行的WPF进程的窗口......

在我的应用程序启动事件怎么办这个:

private void Application_Startup(object sender, StartupEventArgs e) 
{ 
    if(Process.GetProcessesByName(Process.GetCurrentProcess().ProcessName).Count() > 1) 
    { 
     Application.Current.Shutdown(0); 
    } 
} 

回答

1

我发现如何做这项工作!

我的问题通过“Reed Copsey”帮助和Windows SendMessage API解决。 做这件事情,我写在我的window1.xaml.cs这些代码文件中:

 

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Windows; 
using System.Windows.Controls; 
using System.Windows.Data; 
using System.Windows.Documents; 
using System.Windows.Input; 
using System.Windows.Media; 
using System.Windows.Media.Imaging; 
using System.Windows.Navigation; 
using System.Windows.Shapes; 
using System.Reflection; 
using System.Runtime.InteropServices; 
using System.Windows.Interop; 


namespace app1 
{ 
    public partial class window1: Window 
    { 
     public window1() 
     { 
      InitializeComponent();    
     } 
     private void window1_Loaded(object sender, RoutedEventArgs e) 
     { 
      HwndSource source = HwndSource.FromHwnd(new WindowInteropHelper(this).Handle); 
      source.AddHook(new HwndSourceHook(WndProc)); 
     } 
     private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled) 
     { 
      System.Windows.Forms.Message m = System.Windows.Forms.Message.Create(hwnd, msg, wParam, lParam); 
      if (m.Msg == WM_COPYDATA) 
      { 
       // Get the COPYDATASTRUCT struct from lParam. 
       COPYDATASTRUCT cds = (COPYDATASTRUCT)m.GetLParam(typeof(COPYDATASTRUCT)); 

       // If the size matches 
       if (cds.cbData == Marshal.SizeOf(typeof(MyStruct))) 
       { 
        // Marshal the data from the unmanaged memory block to a 
        // MyStruct managed struct. 
        MyStruct myStruct = (MyStruct)Marshal.PtrToStructure(cds.lpData, 
         typeof(MyStruct)); 

        // Display the MyStruct data members. 
        if (myStruct.Message == "Show Up") 
        { 
         this.Show(); 
        } 
       } 
      } 
      return IntPtr.Zero; 
     } 

     internal const int WM_COPYDATA = 0x004A; 

     [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] 
     internal struct MyStruct 
     { 
      [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)] 
      public string Message; 
     } 
     [StructLayout(LayoutKind.Sequential)] 
     internal struct COPYDATASTRUCT 
     { 
      public IntPtr dwData;  // Specifies data to be passed 
      public int cbData;   // Specifies the data size in bytes 
      public IntPtr lpData;  // Pointer to data to be passed 
     } 


    } 
} 

 

我写在我的App.xaml.cs这些代码:

 

using System; 
using System.Collections.Generic; 
using System.Configuration; 
using System.Data; 
using System.Linq; 
using System.Windows; 
using System.Windows.Threading; 
using System.Runtime.InteropServices; 
using System.Security; 

namespace app1 
{  
    public partial class App : Application 
    {  
     [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] 
     internal struct MyStruct 
     { 
      [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)] 
      public string Message; 
     } 



     internal const int WM_COPYDATA = 0x004A; 
     [StructLayout(LayoutKind.Sequential)] 
     internal struct COPYDATASTRUCT 
     { 
      public IntPtr dwData;  // Specifies data to be passed 
      public int cbData;   // Specifies the data size in bytes 
      public IntPtr lpData;  // Pointer to data to be passed 
     } 
     [SuppressUnmanagedCodeSecurity] 
     internal class NativeMethod 
     {    
      [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)] 
      public static extern IntPtr SendMessage(IntPtr hWnd, int Msg, 
       IntPtr wParam, ref COPYDATASTRUCT lParam); 


      [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)] 
      public static extern IntPtr FindWindow(string lpClassName, string lpWindowName); 
     } 

     private void Application_Startup(object sender, StartupEventArgs e) 
     {    
      if (System.Diagnostics.Process.GetProcessesByName(Process.GetCurrentProcess().ProcessName).Count() > 1) 
      { 
       IntPtr hTargetWnd = NativeMethod.FindWindow(null, "window1"); 
       if (hTargetWnd == IntPtr.Zero) 
       {      
        return; 
       } 
       MyStruct myStruct; 
       myStruct.Message = "Show Up"; 
       int myStructSize = Marshal.SizeOf(myStruct); 
       IntPtr pMyStruct = Marshal.AllocHGlobal(myStructSize); 
       try 
       { 
        Marshal.StructureToPtr(myStruct, pMyStruct, true); 

        COPYDATASTRUCT cds = new COPYDATASTRUCT(); 
        cds.cbData = myStructSize; 
        cds.lpData = pMyStruct; 
        NativeMethod.SendMessage(hTargetWnd, WM_COPYDATA, new IntPtr() , ref cds); 

        int result = Marshal.GetLastWin32Error(); 
        if (result != 0) 
        {      
        } 
       } 
       finally 
       { 
        Marshal.FreeHGlobal(pMyStruct); 
       } 
       Application.Current.Shutdown(0); 
      }    
     } 

    } 
} 
 

就是这样。 :D

6

一个典型的方法是使用Mutex。这样可以防止启动第二个实例(或者,在应用程序的第二个实例内检测到它)。

此时,您可以通知原始应用程序实例自行“显示”。这里是a good article describing the entire process in detail(尽管使用Windows窗体)。

对于WPF应用程序,您需要将此逻辑放入应用程序的启动逻辑中,并在您想要显示的WPF窗口中输入add an HwndSourceHook to process the windows message

相关问题