C# 调用 Win10/11 文件关联对话框
方法一:调用未公开接口 IOpenWithLauncher
Adobe Acrobat 应该是调用的未公开接口方法
[ComImport]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
[Guid("6A283FE2-ECFA-4599-91C4-E80957137B26")]
interface IOpenWithLauncher
{
[PreserveSig]
int Launch(IntPtr hWndParent,
[MarshalAs(UnmanagedType.LPWStr)] string lpszPath,
IMMERSIVE_OPENWITH flags);
}
[Flags]
enum IMMERSIVE_OPENWITH
{
NONE = 0,
OVERRIDE = 0x1,
DONOT_EXEC = 0x4,
PROTOCOL = 0x8,
URL = 0x10,
USEPOSITION = 0x20,
DONOT_SETDEFAULT = 0x40,
ACTION = 0x80,
ALLOW_EXECDEFAULT = 0x100,
NONEDP_TO_EDP = 0x200,
EDP_TO_NONEDP = 0x400,
CALLING_IN_APP = 0x800,
};
public static void ShowSetAssocDialog(string extension)
{
var CLSID_ExecuteUnknown = new Guid("{E44E9428-BDBC-4987-A099-40DC8FD255E7}");
var obj = Activator.CreateInstance(Type.GetTypeFromCLSID(CLSID_ExecuteUnknown));
if (obj is IOpenWithLauncher launcher)
{
launcher.Launch(IntPtr.Zero, extension, IMMERSIVE_OPENWITH.DONOT_EXEC);
Marshal.ReleaseComObject(launcher);
}
}
方法二:通过模拟点击属性对话框“更改”打开方式
此方法来自两年前我的自问自答,代码引用了 《C# 窗口过程消息处理 WndProc》 中的附加到其他窗口辅助类
Bandizip 使用的这种方法
[DllImport("shell32.dll", CharSet = CharSet.Auto)]
static extern bool SHObjectProperties(IntPtr hWnd, SHOP shopObjectType, string pszObjectName, string pszPropertyPage);
enum SHOP
{
PRINTERNAME = 1,
FILEPATH = 2,
VOLUMEGUID = 4
}
[DllImport("kernel32.dll")]
static extern int GetCurrentProcessId();
[DllImport("user32.dll")]
static extern int GetWindowThreadProcessId(IntPtr hWnd, out int lpdwProcessId);
[DllImport("user32.dll", CharSet = CharSet.Auto)]
static extern int GetClassName(IntPtr hWnd, StringBuilder lpClassName, int nMaxCount);
[DllImport("user32.dll", CharSet = CharSet.Auto)]
static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, int nMaxCount);
[DllImport("user32.dll")]
static extern bool SetForegroundWindow(IntPtr hWnd);
[DllImport("user32.dll")]
static extern bool EnumWindows(EnumWindowsProc lpEnumFunc, IntPtr lParam);
delegate bool EnumWindowsProc(IntPtr hWnd, IntPtr lParam);
public static void ShowSetAssocDialog(string extension)
{
string fileName = Path.ChangeExtension(Path.GetRandomFileName(), extension);
string filePath = Path.Combine(Path.GetTempPath(), fileName);
fileName = Path.GetFileNameWithoutExtension(fileName);
File.WriteAllText(filePath, string.Empty); // 创建临时文件
var frame = new DispatcherFrame();
int pid = GetCurrentProcessId();
SHObjectProperties(IntPtr.Zero, SHOP.FILEPATH, filePath, null); // 显示属性对话框
while (true)
{
bool found = !EnumWindows((hWnd, lParam) => // 枚举窗口
{
GetWindowThreadProcessId(hWnd, out int id);
if (id == pid) // 比较进程 id
{
const int MAX_PATH = 260;
var sb = new StringBuilder(MAX_PATH);
GetClassName(hWnd, sb, sb.Capacity);
if (sb.ToString() == "#32770") // 对话框类名
{
GetWindowText(hWnd, sb, sb.Capacity);
if (sb.ToString().Contains(fileName)) // 对话框标题是否包含文件名
{
SetWindowPos(hWnd, IntPtr.Zero, 0, 0, 0, 0, SWP.HIDEWINDOW);// 隐藏属性对话框
MessageHooker.AddHook(hWnd, (ref Message m) =>
{
const int PSM_CHANGED = 0x400 + 104;
if (m.Msg == PSM_CHANGED)// 监测属性表页更改
{
frame.Continue = false;
PostMessage(hWnd, WM.CLOSE, 0, 0); // 等效 EndDialog(hWnd, 0)
}
return false;
});
SetForegroundWindow(hWnd);
SendKeys.SendWait("%C");// ALT + C 快捷键
return false;
}
}
}
return true;
}, IntPtr.Zero);
if (found) break;
}
File.Delete(filePath); // 删除临时文件
Dispatcher.PushFrame(frame);
}
相关资料
How to call the "Open With" dialog used to associate file formats in Windows 10 or 11?
https://learn.microsoft.com/en-us/windows/win32/controls/psm-changed
C# 调用 Win10/11 文件关联对话框的更多相关文章
- [VB.NET]调用系统的文件夹选择对话框
以下示例代码展示如何调用系统的文件夹选择对话框: Private Function SelectFolder(ByVal Describe As String, Optional ByVal Show ...
- LaTeX-WinEdt 编辑器和 PDF 文件的 Acrobat 11 程序关联
WinEdt 编辑器和 PDF 文件的 Acrobat 11 程序关联 CTeX 套装 2.8 版本以后,也就是09年9月以后的版本加入了SumatraPDF程序,将PDF文件与Acrobat程序取消 ...
- WPF中使用文件浏览对话框的几种方式
原文:WPF中使用文件浏览对话框的几种方式 WPF本身并没有为我们提供文件浏览的控件, 也不能直接使用Forms中的控件,而文件浏览对话框又是我们最常用的控件之一. 下面是我实现的方式 方式1: 使用 ...
- 。net 添加或获取文件关联
文件关联设置 2011-02-07 14:25:36| 分类: VB.net2008或2010 | 标签:文件关联 |举报|字号 订阅 原理:以后缀名为.txt为例 方式一: 1.在注册 ...
- CodeSmith使用总结--下拉列表和文件夹对话框属性
上一篇有点短了,因为实在没有什么可说的,这一篇会多一点.O(∩_∩)O~ 一.下拉列表 关于如何在CodeSmith中创建一个下拉列表的属性框其实很简单,是要使用C#中的枚举就行了,看操作. 首先定义 ...
- delphi调用外部程序打开文件
delphi调用外部程序打开文件 ShellExecute的各种用法 一.利用系统默认的邮件收发器发送电子邮件 Uses ..., ShellAPI; Var lpHwnd: HWND; lpOper ...
- 文件对话框WPF(5)----文件浏览对话框
废话就不多说了,开始... WPF中文件浏览对话框的实现可以利用Windows API Code Pack,它是一个用于访问Windows Vista/7 特性的托管代码函数库,但并没有包含在.NET ...
- loadrunner 脚本开发-调用java jar文件远程操作Oracle数据库测试
调用java jar文件远程操作Oracle数据库测试 by:授客 QQ:1033553122 测试环境 数据库:linux 下Oracle_11g_R2 Loadrunner:11 备注:想学ora ...
- 迁移桌面程序到MS Store(4)——桌面程序调用Win10 API
上一篇我们讨论了如何在转制的桌面程序中,通过StartupTask来实现转制版本的开机自启动.实际操作中,我们通过编辑Packaging工程中的Package.appxmanifest文件,来添加自启 ...
- VC++ 打开文件或文件夹对话框的实现方法
实际工作开发中,由于各种应用,我们需要调用系统的打开文件对话框或者打开文件夹对话框,或两者兼有.特总结了常用的实现方法,仅供开发参考. 1. 打开文件对话框 常用的方法是使用系统的CFileDialo ...
随机推荐
- [.NET] 使用客户端缓存提高API性能
使用客户端缓存提高API性能 摘要 在现代应用程序中,性能始终是一个关键的考虑因素.无论是提高响应速度,降低延迟,还是减轻服务器负载,开发者都在寻找各种方法来优化他们的API.在Web开发中,利用客户 ...
- ASP.NET Core - 日志记录系统(二)
本篇接着上一篇 [ASP.NET Core - 日志记录系统(一)] 往下讲,所以目录不是从 1 开始的. 2.4 日志提供程序 2.4.1 内置日志提供程序 ASP.NET Core 包括以下日志记 ...
- 国家和地区代码列表,ISO 3166-1:2006
本文根据ISO 3166-1:2006(International Standard Norme Internationale) 英文版(含2007年补充说明)整理.与ISO 3166-1:1997相 ...
- SpringBoot(四) - 整合Mybatis,逆向工程,JPA,Mybatis-plus
1.SpringBoot整合MyBatis 1.1 application.yml # 数据源配置 spring: datasource: driver-class-name: com.mysql.c ...
- 系统提示msvcp120.dll丢失如何解决
最近有位win7系统用户反映,自己安装完游戏开始玩的时候,系统却提示:示msvcp120.dll丢失,这导致了游戏无法正常运行,这让用户很是苦恼,不知道电脑如何解决,为此非常苦恼,那么win7系统提示 ...
- Go语言【Gin框架】:JSON、AsciiJSON、PureJSON和SecureJSON的区别
在Go语言中,JSON.AsciiJSON.PureJSON 和 SecureJSON 是Gin框架用于发送JSON响应的方法. 1. c.JSON 功能:将提供的数据序列化为标准的JSON格式,并将 ...
- C#客户端Json转DataTable
本文转自 https://blog.csdn.net/pinebud55/article/details/52240287 感谢pinebud55分享 之前我们有讨论过c#是如何处理json的,在我的 ...
- 创建react脚手架(项目)
现在安装 react 脚手架的有三种, react-boilerplate react-redux-starter-kit create-react-app(国内主要运用这一种) 1==>npm ...
- Java开发自学第一天
Java学习日志 Day 01|2025/2/11|累计1天 今日学习时长 6小时 当日学习目标 1.了解JVM.JDK.JRE 2.学习Idea开发工具的基本使用 3.基本语法:运算符.数据类型.变 ...
- 历时两天半由浅入深总结了20道Vue高频面试题
作为一个程序员如果你想要找到你心仪的工作,不可避免的就会问到很多八股文,虽然有的和工作没有半毛钱关系,但是你如果想要通过面试还必须得会.所以我最近开始总结一些面试题,一是为了加强自己的理解能够找到一份 ...