3

window1 という名前のウィンドウを持つ app1 という WPF アプリケーションがあります。ユーザーが の閉じるボタンをクリックするとwindow1、アプリは閉じず、window1 は非表示になります ( this.hide())。

アプリケーションの別のインスタンスが起動時にすでに実行されているかどうかを確認したい。もしそうなら、私はすでに実行中のインスタンスを表示し、新しいインスタンスを終了したいと考えています。

どうやってやるの?

プロセスを確認する方法と現在のアプリを閉じる方法は知っていますが、実行中の別の WPF プロセスからウィンドウを表示する方法がわかりません...

私のアプリの起動イベントでは、これを行います:

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

2 に答える 2

6

これに対する典型的なアプローチは、Mutex を使用することです。これにより、2 番目のインスタンスが開始されないようにすることができます (または、アプリケーションの 2 番目のインスタンス内でそれを検出できます)。

その時点で、元のアプリケーション インスタンスにそれ自体を「表示」するよう通知できます。これは、プロセス全体を詳細に説明した優れた記事です (ただし、Windows フォームを使用しています)。

WPF アプリケーションの場合、このロジックをアプリケーションのスタートアップ ロジックに配置し、HwndSourceHook を追加して、表示する WPF ウィンドウのウィンドウ メッセージを処理する必要があります。

于 2012-07-09T16:50:11.470 に答える
2

働き方がわかった!

「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

于 2012-07-09T17:47:53.050 に答える