當雙擊打開自定義格式的文件時,但願使用當前正在運行的進程,而不是另起一個進程。shell
本文介紹一種方式解決如上問題,方案參考user3582780的解答app
參考連接,具體步驟以下:ide
首先,當雙擊自定義格式文件進行打開時,會將該文件的路徑做爲參數傳遞給程序,所以打開程序應響應啓動參數。.net
在WPF應用程序中,Application的OnStartup方法會攜帶程序的啓動參數(經過Environment也可獲取啓動參數)。code
當雙擊自定義格式文件時,如有一個實例正在運行,並不會直接使用該實例打開文件,而是會從新打開一個實例。此時須要將新實例的啓動參數傳遞給當前實例並關閉新實例。blog
本文使用發送窗口消息的方式處理該問題,即便用Win32的SendMessage接口發送參數給當前實例窗口,當前實例響應消息處理便可。具體實現方案以下:接口
// App private static Mutex mutex; protected override void OnStartup(StartupEventArgs e) { mutex = new Mutex(true, "myapp", out bool ret); if(!ret) Reopen(e); // ... } private void Reopen(StartupEventArgs e) { // IntPtr hwnd = FindWindow(null, "window title"); if(e.Args.Length > 0) SendMessage(); Environment.Exit(0); } private void SendMessage(IntPtr hwnd, string data) { CopyDataStruct cds = new CopyDataStruct(); try { cds.cbData = (data.Length + 1) * 2; // number of bytes cds.lpData = Win32.LocalAlloc(0x40, cds.cbData); // known local-pointer in RAM Marshal.Copy(data.ToCharArray(), 0, cds.lpData, data.Length); // Copy data to preserved local-pointer cds.dwData = (IntPtr)1; SendMessage(hwnd, WM_COPYDATA, IntPtr.Zero, ref cds); } finally { cds.Dispose(); } } // Window private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled) { if(msg == WM_COPYDATA) { CopyDataStruct st = (CopyDataStruct)Marshal.PtrToStructure(lParam, typeof(CopyDataStruct)); string strData = Marshal.PtrToStringUni(st.lpData); OpenFile(strData); Activate(); } return IntPtr.Zero; }