网站首页 全球最实用的IT互联网站!

人工智能P2P分享Wind搜索发布信息网站地图标签大全

当前位置:诺佳网 > 软件工程 > 后端开发 > .Net >

C# 调用 Win10/11 文件关联对话框

时间:2025-04-02 15:32

人气:

作者:admin

标签:

导读:方法一:调用未公开接口#160;IOpenWithLauncher Adobe Acrobat 应该是调用的未公开接口方法 [ComImport] [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] [Guid(quot;6A283FE2-...

方法一:调用未公开接口 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);
}

相关资料

Redirecting Open With in Properties Dialog in Windows 10

How to call the "Open With" dialog used to associate file formats in Windows 10 or 11?

温馨提示:以上内容整理于网络,仅供参考,如果对您有帮助,留下您的阅读感言吧!
相关阅读
本类排行
相关标签
本类推荐

CPU | 内存 | 硬盘 | 显卡 | 显示器 | 主板 | 电源 | 键鼠 | 网站地图

Copyright © 2025-2035 诺佳网 版权所有 备案号:赣ICP备2025066733号
本站资料均来源互联网收集整理,作品版权归作者所有,如果侵犯了您的版权,请跟我们联系。

关注微信