问题形容
当双击关上自定义格局的文件时,心愿应用以后正在运行的过程,而不是另起一个过程。
本文介绍一种形式解决如上问题,计划参考user3582780的解答
设置自定义文件格式的默认打开方式
参考链接,具体步骤如下:
- 在HKEY_CLASSES_ROOT中新建项,命名为自定义文件格式(如.custom),设置其默认值(如mycustom);
- 在HKEY_CLASSES_ROOT中新建项,命名为步骤1中的默认值,即mycustom;
- 在mycustom中新建项,命名为DefaultIcon,设置默认值(Icon门路);
- 在mycustom中新建项,命名为shell,在shell中持续新建项open,在open中新建项command,设置其默认值(格局:程序门路 "%1")
应用以后实例关上文件
首先,当双击自定义格式文件进行关上时,会将该文件的门路作为参数传递给程序,因而关上程序应响应启动参数。
在WPF应用程序中,Application的OnStartup办法会携带程序的启动参数(通过Environment也可获取启动参数)。
当双击自定义格式文件时,若有一个实例正在运行,并不会间接应用该实例关上文件,而是会从新关上一个实例。此时须要将新实例的启动参数传递给以后实例并敞开新实例。
本文应用发送窗口音讯的形式解决该问题,即应用Win32的SendMessage接口发送参数给以后实例窗口,以后实例响应音讯解决即可。具体实现计划如下:
// Appprivate 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(); }}// Windowprivate 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;}