问题描述

当双击打开自定义格式的文件时,希望使用当前正在运行的进程,而不是另起一个进程。

本文介绍一种方式解决如上问题,方案参考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;
}

WPF -- 使用当前进程打开自定义文件的一种方式的更多相关文章

  1. C#中的Excel操作【1】——设置Excel单元格的内容,打开Excel文件的一种方式

    前言 作为项目管理大队中的一员,在公司里面接触最多的就是Excel文件了,所以一开始就想从Excel入手,学习简单的二次开发,开始自己的编程之路! 程序界面 功能说明 打开文件按钮,可以由使用者指定要 ...

  2. Linux 利用进程打开的文件描述符(/proc)恢复被误删文件

    Linux 利用进程打开的文件描述符(/proc)恢复被误删文件 在 windows 上删除文件时,如果文件还在使用中,会提示一个错误:但是在 linux 上删除文件时,无论文件是否在使用中,甚至是还 ...

  3. s11.1 lsof:查看进程打开的文件

    功能说明 lsof 全名为list open files,也就是列举系统中已经被打开的文件,通过lsof命令,就可以根据文件找到对应的进程信息,也可以根据进程信息找到进程打开的文件. [语法格式] l ...

  4. lsof恢复进程打开的文件

    工作原理:进程每打开文件都会生成一个文件句柄FD来标识一个文件,进程打开的文件如果没有被释放,可以通过文件句柄FD来恢复删除的文件 注意:适合恢复进程一直在打开一个文件,例如日志文件,如果配置文件进程 ...

  5. Linux 系统管理命令 - lsof - 查看进程打开的文件

    命令详解 重要星级: ★★★★★ 功能说明: 全名为 list open files,也就是列举系统中已经被打开的文件,通过 lsof 命令,就可以根据文件找到对应的进程信息,也可以根据进程信息找到进 ...

  6. lsof 查看打开了一个文件的有哪些进程 统计那个进程打开的文件最多

    lsof | grep /lib64/libc-2.12.so | wc   == 查看打开了一个文件的有哪些进程 lsof | awk '{print $2,$1}' | sort | uniq - ...

  7. 打开cad文件的几种方法

    转自原文 打开cad文件的几种方法 IWorkspaceFactory pWorkspaceFactory; IFeatureWorkspace pFeatureWorkspace; IFeature ...

  8. 加载xib文件的两种方式

    一.加载xib文件的两种方式 1.方法一(NewsCell是xib文件的名称) NSArray *objects = [[NSBundle mainBundle] loadNibNamed:@&quo ...

  9. PHP导出excel文件的几种方式

    PHP导出excel文件的几种方式 先说说动态生成的内容当作文件来下载的方法: 1.通过把Content-Type设置为application/octet-stream,可以把动态生成的内容当作文件来 ...

随机推荐

  1. nasm astrchr函数 x86

    xxx.asm: %define p1 ebp+8 %define p2 ebp+12 %define p3 ebp+16 section .text global dllmain export as ...

  2. 揭秘高倍矿币 Baccarat BGV,为何NGK DeFi的财富效应如此神奇?

    作为区块链4.0代表的NGK公链,这次也将借助它自己的DeFi版块NGK Baccarat,开启属于它自己的千倍财富之旅. 如果说,比特币能让没有银行账户的人,可以在全球任何时间.地点都能自由进行交易 ...

  3. Java的super、this、重写

    Java的super.this.重写 一.super的注意点: super调用父类的构造方法,必须在构造方法的第一个: super只能出现在子类的构造方法或者方法中: this和super不能同时调用 ...

  4. 「TcaplusDB知识库」概念(表、键、记录、索引)

       TcaplusDB作为一款NoSQL数据库,语法与传统的SQL关系库有所差异.本文将详细介绍TcaplusDB表.记录.索引这三个数据库中常用术语在TcaplusDB中的概念与意义. 术语\概念 ...

  5. SpringCloud之服务注册中心

    1.Eureka 1.1RestTemplate 它提供了多种访问远程http服务的方法,是一种简单便捷的访问restful服务模板类,是spring提供的用于访问Rest服务的客户端模板工具集. 1 ...

  6. COM技术中的VARIANT and VARIANTARG

    VARIANT and VARIANTARG Use VARIANTARG to describe arguments passed within DISPPARAMS, and VARIANT to ...

  7. docker里运行docker命令

    一.概述 现有环境的jenkins是在docker里面运行的,需要执行docker相关命令才行. 关于基于docker搭建jenkins,请参考链接: https://www.cnblogs.com/ ...

  8. SpringBoot(十一): Spring Boot集成Redis

    1.在 pom.xml 中配置相关的 jar 依赖: <!-- 加载 spring boot redis 包 --> <dependency> <groupId>o ...

  9. 剑指 Offer 60. n个骰子的点数 + 动态规划 + 空间优化

    剑指 Offer 60. n个骰子的点数 Offer_60 题目详情 题解分析 package com.walegarrett.offer; /** * @Author WaleGarrett * @ ...

  10. 【转载】Android的事件分发(dispatchTouchEvent),拦截(onInterceptTouchEvent)与处理(onTouchEvent)

    出处:https://blog.csdn.net/caifengyao/article/details/65437695 在Android中,View的结构是树状的,所以,当触发触摸事件的时候,其事件 ...