关于WPF:WPF-使用当前进程打开自定义文件的一种方式

10次阅读

共计 1571 个字符,预计需要花费 4 分钟才能阅读完成。

问题形容

当双击关上自定义格局的文件时,心愿应用以后正在运行的过程,而不是另起一个过程。

本文介绍一种形式解决如上问题,计划参考 user3582780 的解答

设置自定义文件格式的默认打开方式

参考链接,具体步骤如下:

  1. 在 HKEY_CLASSES_ROOT 中新建项,命名为自定义文件格式(如.custom),设置其默认值(如 mycustom);
  2. 在 HKEY_CLASSES_ROOT 中新建项,命名为步骤 1 中的默认值,即 mycustom;
  3. 在 mycustom 中新建项,命名为 DefaultIcon,设置默认值(Icon 门路);
  4. 在 mycustom 中新建项,命名为 shell,在 shell 中持续新建项 open,在 open 中新建项 command,设置其默认值(格局:程序门路 “%1″)

应用以后实例关上文件

首先,当双击自定义格式文件进行关上时,会将该文件的门路作为参数传递给程序,因而关上程序应响应启动参数。

在 WPF 应用程序中,Application 的 OnStartup 办法会携带程序的启动参数(通过 Environment 也可获取启动参数)。

当双击自定义格式文件时,若有一个实例正在运行,并不会间接应用该实例关上文件,而是会从新关上一个实例。此时须要将新实例的启动参数传递给以后实例并敞开新实例。

本文应用发送窗口音讯的形式解决该问题,即应用 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;
}
正文完
 0