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 ...
随机推荐
- CDS标准视图:维护通知活动信息 I_MaintNotificationActyData
视图名称:维护通知活动信息 I_MaintNotificationActyData 视图类型:基础 视图代码: 点击查看代码 @AbapCatalog.sqlViewName: 'INOTIFACTY ...
- biancheng-Spring
目录http://c.biancheng.net/spring/spring-abc.html 1Spring是什么2Spring体系结构3Spring开发环境搭建4第一个Spring程序5Sprin ...
- Java集合容器面试题
Java常用集合类有哪些?Collection接口的子接口包括:Set接口和List接口Map接口的实现类主要有:HashMap.TreeMap.Hashtable.ConcurrentHashMap ...
- docker没有vi不能执行yum报Device or resource busy
最近在使用docker的过程中发现一个问题,就是想用vim编辑器编辑一个文件,发现连vi都没有. 于是想到一个办法用docker cp来解决问题: 首先执行docker ps -a查看容器的id 然后 ...
- Integer包装类中的IntegerCache结构
public void test3() { Integer i = new Integer(1); Integer j = new Integer(1); System.out.println(i = ...
- ARM单片机知识点
1.STM32编译信息 代码占用FLASH 大小为:Code + RO-data, 7420字节(5054+2366),所用的RAM 大小为:RW-data + ZI-data, 8576(372+8 ...
- java重载-构造方法也存在重载-数据类型的提升
重载 1.一个类中不能声明多个相同的方法,属性. 2.上面的相同指的是方法名,参数列表相同.和返回值类型无关. 3.如果方法名相同,但是参数列表(个数,顺序,类型)不相同,会认为是不同的方法,在jav ...
- 独立开发经验谈:如何借助 AI 辅助产品 UI 设计
我在业余时间开发了一款自己的独立产品:升讯威在线客服与营销系统.陆陆续续开发了几年,从一开始的偶有用户尝试,到如今线上环境和私有化部署均有了越来越多的稳定用户,在这个过程中,我也积累了不少如何开发运营 ...
- 使用SOUI播放视频
播放视频是一个常规需求. 如果将每一个视频帧转换成rgb格式,再使用gdi贴图,效率会很低,只能适合分辨率很低的视频,1080P全屏软渲染一般的电脑都撑不住. 因此渲染视频通常需要启用硬件渲染.开启硬 ...
- 异常:java.lang.reflect.InvocationTargetException
在产生这个问题的时候,以为是代码某个类又改动了.但是对比了git,发现并没有改动,测试环境代码照跑,故又重新拉了一份重新部署,仍然报同样的错.解决过程中,试了以下网上各种方法,均无效果. 1.包重复. ...