C# 如何在代码中提示“选择默认程序”?

C# 如何在代码中提示“选择默认程序”?,c#,winforms,C#,Winforms,我正在编写一个列表框中填充项目的程序,当您右键单击该项目时,关联菜单将弹出,并有一个选项选择call Open with,我的问题是如何使choose a default program窗口显示,如下图所示 我知道您需要执行此过程。启动以打开它,但我不知道exe名称。打开时使用。。。Windows Shell中的对话框是explorer.exe的一部分,不是它自己的程序。您过去可以使用openas动作动词来访问它,但从Vista开始,它被重新定义为以管理员身份运行 还有一些技巧。其他答案演示了O

我正在编写一个列表框中填充项目的程序,当您右键单击该项目时,关联菜单将弹出,并有一个选项选择call Open with,我的问题是如何使choose a default program窗口显示,如下图所示


我知道您需要执行此过程。启动以打开它,但我不知道exe名称。

打开时使用。。。Windows Shell中的对话框是explorer.exe的一部分,不是它自己的程序。您过去可以使用openas动作动词来访问它,但从Vista开始,它被重新定义为以管理员身份运行

还有一些技巧。其他答案演示了OpenAs_RunDLL方法;但是,应该知道,尤其是在Windows Vista和更高版本上。API中记录并因此支持的入口点是shell32.dll中另一个名为SHOpenWithDialog的函数。下面是基于P/Invoke的代码,可以实现以下功能:

public static class OpenWithDialog
{
    [DllImport("shell32.dll", EntryPoint = "SHOpenWithDialog", CharSet = CharSet.Unicode)]
    private static extern int SHOpenWithDialog(IWin32Window parent, ref OpenAsInfo info);

    private struct OpenAsInfo
    {
        [MarshalAs(UnmanagedType.LPWStr)]
        public string FileName;
        [MarshalAs(UnmanagedType.LPWStr)]
        public string FileClass;
        [MarshalAs(UnmanagedType.I4)]
        public OpenAsFlags OpenAsFlags;
    }

    [Flags]
    public enum OpenAsFlags
    {
        None = 0x00,
        AllowRegistration = 0x01,
        RegisterExt = 0x02,
        ExecFile = 0x04,
        ForceRegistration = 0x08,
        HideRegistration = 0x20,
        UrlProtocol = 0x40,
        FileIsUri = 0x80,
    }

    public static int Show(string fileName, IWin32Window parent = null, string fileClass = null, OpenAsFlags openAsFlags = OpenAsFlags.ExecFile)
    {
        var openAsInfo = new OpenAsInfo
                             {
                                 FileName = fileName,
                                 FileClass = fileClass,
                                 OpenAsFlags = openAsFlags
                             };

        return SHOpenWithDialog(parent, ref openAsInfo);
    }
}
在打开的窗口中,如果您从未连接消息循环的线程运行程序,则浏览按钮将冻结该程序;还建议您传入表单实例或作为父参数


以HiderRegistration开头的标志是Vista+,最后一个FileiURI是Windows 8+;在以前的版本中,它们将被忽略,这可能会导致不良行为。默认情况下,openAsFlags参数设置为使用所选程序打开文件,这是RunDLL解决方案无法始终工作的原因之一。此值是OpenAs_RunDLL的第二个参数的一部分,该参数未包含在RunDLL命令行中。返回值应为零或正;负值是符合WinAPI HRESULT标准的错误。

您可以使用这种方式直接显示“打开方式”对话框:

string FilePath = "C:\\Text.txt";//Your File Path
System.Diagnostics.Process proc = new System.Diagnostics.Process();
proc.EnableRaisingEvents = false;
proc.StartInfo.FileName = "rundll32.exe";
proc.StartInfo.Arguments = "shell32,OpenAs_RunDLL " + FilePath;
proc.Start();

有没有办法只设置应用程序而不在设置后打开它?我只是尝试设置应用程序,而不是在之后实际打开程序。e、 g.如果我将所有.txt文件设置为使用记事本打开,我不希望它使用txt文件打开记事本,而只是设置它。这可能吗?编辑注册表可能会更好;在“打开方式”对话框中所做的选择存储在HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\中。您的程序需要完全信任才能执行此操作。Zer0>这可能吗?不可靠。用户的默认设置是由Windows管理的,我上次听说故意不记录的方式/位置,其实现可能会有更改,恕不另行通知。如果没有API来设置它,也不应该有,那么不,你不应该直接对系统进行黑客攻击来设置它。这样做会让你无法区分恶意软件和它不那么直接邪恶的用户体验,而用户是不受控制的近亲。应用程序滥用了直接设置用户默认值的功能,因此Windows采取了一些措施来防止直接操作。此入口点未记录,并不总是按预期工作,可能会发生更改,恕不另行通知。KeithS的OpenWithDialog解决方案是正确的方法。