Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何使应用程序名称显示在“打开方式”列表中?_C#_Wpf_Registry_Open With - Fatal编程技术网

C# 如何使应用程序名称显示在“打开方式”列表中?

C# 如何使应用程序名称显示在“打开方式”列表中?,c#,wpf,registry,open-with,C#,Wpf,Registry,Open With,这是我问题的继续。我正在为*.bmp类型创建一个“打开方式”列表。根据该问题的答案,我已从注册表项创建了“打开方式”列表中的应用程序列表 public void RecommendedPrograms(string ext) { string baseKey = @"Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\." + ext; using (RegistryKey r

这是我问题的继续。我正在为*.bmp类型创建一个“打开方式”列表。根据该问题的答案,我已从注册表项创建了“打开方式”列表中的应用程序列表

   public void RecommendedPrograms(string ext)
    {


        string baseKey = @"Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\." + ext;

        using (RegistryKey rk = Registry.CurrentUser.OpenSubKey(baseKey + @"\OpenWithList"))
        {
            if (rk != null)
            {
                string mruList = (string)rk.GetValue("MRUList");
                if (mruList != null)
                {
                    foreach (char c in mruList.ToString())
                    {
                        string str=rk.GetValue(c.ToString()).ToString();
                        if (!progs.Contains(str))
                        {
                            progs.Add(str);
                        }
                    }
                }
            }
        }

        using (RegistryKey rk = Registry.CurrentUser.OpenSubKey(baseKey + @"\OpenWithProgids"))
        {
            if (rk != null)
            {
                foreach (string item in rk.GetValueNames())
                    progs.Add(item);
            }
        }

        using (RegistryKey rk = Registry.ClassesRoot.OpenSubKey("." + ext + @"\OpenWithList"))
        {
            if (rk != null)
            {
                foreach (var item in rk.GetSubKeyNames())
                {
                    if (!progs.Contains(item))
                    {
                        progs.Add(item.ToString());
                    }
                }
            }
        }
        using (RegistryKey rk = Registry.ClassesRoot.OpenSubKey("." + ext + @"\OpenWithProgids"))
        {
            if (rk != null)
            {
                foreach (string item in rk.GetValueNames())
                {
                    if (!progs.Contains(item))
                    {
                        progs.Add(item);
                    }
                }
            }
        }

    }
此方法将返回一个应用程序名称列表,如

  • 画画
  • ehshell.exe
  • MSPaint.exe
  • ois.exe
  • VisualStudio.bmp.10.0
  • QuickTime.bmp
这些是PRGID,我可以从中获取打开特定应用程序所需执行的命令

      public string GetRegisteredApplication(string StrProgID)
    {
        // 
        //  Return registered application by file's extension
        // 
        RegistryKey oHKCR;
        RegistryKey oOpenCmd;
        string command;

        if (Environment.Is64BitOperatingSystem == true)
        {
            oHKCR = RegistryKey.OpenBaseKey(Microsoft.Win32.RegistryHive.ClassesRoot, RegistryView.Registry64);
        }
        else
        {
            oHKCR = RegistryKey.OpenBaseKey(Microsoft.Win32.RegistryHive.ClassesRoot, RegistryView.Registry32);
        }
        try
        {


            oOpenCmd = oHKCR.OpenSubKey(StrProgID + "\\shell\\open\\command");
            if (oOpenCmd == null)
            {
                oOpenCmd = oHKCR.OpenSubKey("\\Applications\\" + StrProgID + "\\shell\\open\\command");
            }
            if (oOpenCmd != null)
            {
                command = oOpenCmd.GetValue(null).ToString();
                oOpenCmd.Close();
            }
            else
            {
                return null;
            }
        }
        catch (Exception ex)
        {
            return null;
        }
        return command;
    }
现在,如何获取必须显示在菜单中的应用程序名称? 每次开始使用新应用程序时,Windows操作系统都会自动从exe文件的版本资源中提取应用程序名称,并将其存储在名为“MuiCache”的注册表项中,以备以后使用。MUICache数据存储在HKEY\U CURRENT\U USER\Software\Classes\Local Settings\Software\Microsoft\Windows\Shell\MUICache下

但是我们不能保证应用程序至少运行过一次。我们也可以直接从文件的版本资源中获取描述密钥,但是我在从命令(如)中分离应用程序路径时遇到了一些问题

%SystemRoot%\System32\rundll32.exe“%ProgramFiles%\Windows照片 查看器\PhotoViewer.dll“,ImageView\u全屏%1

我怎样才能得到姓名信息

下面是我的命令列表

  • “C:\Windows\System32\rundll32.exe\”C:\Program Files\Windows 照片查看器\PhotoViewer.dll\,图像视图\u全屏%1
  • “\”C:\Windows\eHome\ehshell.exe\”\%1“
  • “C:\PROGRA~1\MIF5BA~1\Office14\OIS.EXE/shellOpen\%1”
  • “\”C:\Program Files(x86)\Microsoft Visual Studio 10.0\Common7\IDE\devenv.exe\“/dde”
  • “C:\Program Files(x86)\QuickTime\PictureViewer.exe\%1”

如果您知道命令列表,则可以使用下面给出的代码检索描述

 FileVersionInfo.GetVersionInfo(Path.Combine(Environment.SystemDirectory, "Notepad.exe"));
 FileVersionInfo myFileVersionInfo = FileVersionInfo.GetVersionInfo(Environment.SystemDirectory + "\\Notepad.exe");


    // Print the file name and version number.
    Console.WriteLine("File: " + myFileVersionInfo.FileDescription + '\n' +
       "Version number: " + myFileVersionInfo.FileVersion);

基于Amal的解决方案,您只需要处理两种情况:

1) 启动“C:\Windows\System32\rundll32.exe”的 2) 其他一切

如果您想要一些粗略的内容,可以将“C:\Windows\System32\rundll32.exe”替换为空字符串。将“s”替换为空字符串,将字符串a终止为第一个正斜杠(/)或%,然后修剪结果

您只需要输入所需名称的.dll或.exe名称(使用正则表达式可能会更优雅一些,如果需要处理更多场景,此解决方案将很快变得复杂)


然后通过Amal的一段代码运行它,你应该得到你想要的。

更新:对不起,我误读了你的帖子

只有在基于扩展名而不是基于progID查找默认应用程序名时,这才有帮助

public static class FileAssoc
{
    [DllImport("Shlwapi.dll", CharSet = CharSet.Auto, SetLastError = true)]
    static extern uint AssocQueryString(AssocF flags, AssocStr str, string pszAssoc, string pszExtra, [Out] StringBuilder sOut, [In][Out] ref uint nOut);

    [Flags]
    public enum AssocF
    {
        Init_NoRemapCLSID = 0x1,
        Init_ByExeName = 0x2,
        Open_ByExeName = 0x2,
        Init_DefaultToStar = 0x4,
        Init_DefaultToFolder = 0x8,
        NoUserSettings = 0x10,
        NoTruncate = 0x20,
        Verify = 0x40,
        RemapRunDll = 0x80,
        NoFixUps = 0x100,
        IgnoreBaseClass = 0x200
    }

    public enum AssocStr
    {
        Command = 1,
        Executable,
        FriendlyDocName,
        FriendlyAppName,
        NoOpen,
        ShellNewValue,
        DDECommand,
        DDEIfExec,
        DDEApplication,
        DDETopic
    }

    public static string GetApplicationName(string fileExtensionIncludingDot)
    {
        uint cOut = 0;
        if (AssocQueryString(AssocF.Verify, AssocStr.FriendlyAppName, fileExtensionIncludingDot, null, null, ref cOut) != 1)
            return null;
        StringBuilder pOut = new StringBuilder((int)cOut);
        if (AssocQueryString(AssocF.Verify, AssocStr.FriendlyAppName, fileExtensionIncludingDot, null, pOut, ref cOut) != 0)
            return null;
        return pOut.ToString();
    }
}
你可以这样使用它

string applicationName = FileAssoc.GetApplicationName(".docx");
// results in "Microsoft Office Word"

我的代码,包括检查,以防止一些常见错误…希望它有帮助:-)

使用系统;
使用系统诊断;
使用System.IO;
使用System.Runtime.InteropServices;
使用系统文本;
命名空间HQ.Util.Unmanaged
{
/// 
///用法:string executablePath=FileAssociation.GetExecutFileAssociatedToExtension(路径扩展,“打开”);
///用法:string命令FileAssociation.GetExecCommandAssociatedToExtension(路径扩展,“打开”);
/// 
公共静态类文件关联
{
/// 
/// 
/// 
/// 
/// 
///如果未找到,则返回null
公共静态字符串GetExecCommandAssociatedToExtension(字符串扩展,字符串谓词=null)
{
如果(分机[0]!='。)
{
ext=“.”+ext;
}
string executablePath=fileextensioninfo(AssocStr.Command,ext,verb);
//确保在Windows 8或更高版本中不返回与OpenWith.exe关联的默认可执行文件
如果(!string.IsNullOrEmpty(executablePath)&&File.Exists(executablePath)&&
!executablePath.ToLower().EndsWith(“.dll”))
{
if(executablePath.ToLower().EndsWith(“openwith.exe”))
{
return null;//“OpenWith.exe”是未知扩展名的windows 8或更高版本的默认值。我不希望将其作为关联文件
}
返回可执行路径;
}
返回可执行路径;
}
/// 
/// 
/// 
/// 
/// 
///如果未找到,则返回null
公共静态字符串GetExecFileAssociatedToExtension(字符串扩展,字符串谓词=null)
{
如果(分机[0]!='。)
{
ext=“.”+ext;
}
string executablePath=fileextensioninfo(AssocStr.Executable,ext,verb);//仅适用于“open”verb
if(string.IsNullOrEmpty(executablePath))
{
executablePath=FileExtensionInfo(AssocStr.Command,ext,verb);//查找除“open”之外的任何其他动词的命令都是必需的
//只提取路径
如果(!string.IsNullOrEmpty(executablePath)&&executablePath.Length>1)
{
如果(可执行路径[0]='''''')
{
executablePath=executablePath.Split(“\”)[1];
}
else if(可执行路径[0]='\'')
{
executablePath=executablePath.Split('\'')[1];
}
}
}
//确保在Windows 8或更高版本中不返回与OpenWith.exe关联的默认可执行文件
如果(!string.IsNullOrEmpty(executablePath)&&File.Exists(executablePath)&&
!executablePath.ToLower().EndsWith(“.dll”))
{
if(executablePath.ToLower().EndsWith(“openwith.exe”))
{
重新
using System;
using System.Diagnostics;
using System.IO;
using System.Runtime.InteropServices;
using System.Text;

namespace HQ.Util.Unmanaged
{
    /// <summary>
    /// Usage: string executablePath = FileAssociation.GetExecFileAssociatedToExtension(pathExtension, "open");
    /// Usage: string command FileAssociation.GetExecCommandAssociatedToExtension(pathExtension, "open");
    /// </summary>
    public static class FileAssociation
    {
        /// <summary>
        /// 
        /// </summary>
        /// <param name="ext"></param>
        /// <param name="verb"></param>
        /// <returns>Return null if not found</returns>
        public static string GetExecCommandAssociatedToExtension(string ext, string verb = null)
        {
            if (ext[0] != '.')
            {
                ext = "." + ext;
            }

            string  executablePath = FileExtentionInfo(AssocStr.Command, ext, verb);

            // Ensure to not return the default OpenWith.exe associated executable in Windows 8 or higher
            if (!string.IsNullOrEmpty(executablePath) && File.Exists(executablePath) &&
                !executablePath.ToLower().EndsWith(".dll"))
            {
                if (executablePath.ToLower().EndsWith("openwith.exe"))
                {
                    return null; // 'OpenWith.exe' is th windows 8 or higher default for unknown extensions. I don't want to have it as associted file
                }
                return executablePath;
            }
            return executablePath;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="ext"></param>
        /// <param name="verb"></param>
        /// <returns>Return null if not found</returns>
        public static string GetExecFileAssociatedToExtension(string ext, string verb = null)
        {
            if (ext[0] != '.')
            {
                ext = "." + ext;
            }

            string executablePath = FileExtentionInfo(AssocStr.Executable, ext, verb); // Will only work for 'open' verb
            if (string.IsNullOrEmpty(executablePath))
            {
                executablePath = FileExtentionInfo(AssocStr.Command, ext, verb); // required to find command of any other verb than 'open'

                // Extract only the path
                if (!string.IsNullOrEmpty(executablePath) && executablePath.Length > 1) 
                {
                    if (executablePath[0] == '"')
                    {
                        executablePath = executablePath.Split('\"')[1];
                    }
                    else if (executablePath[0] == '\'')
                    {
                        executablePath = executablePath.Split('\'')[1];
                    }
                }
            }

            // Ensure to not return the default OpenWith.exe associated executable in Windows 8 or higher
            if (!string.IsNullOrEmpty(executablePath) && File.Exists(executablePath) &&
                !executablePath.ToLower().EndsWith(".dll"))
            {
                if (executablePath.ToLower().EndsWith("openwith.exe"))
                {
                    return null; // 'OpenWith.exe' is th windows 8 or higher default for unknown extensions. I don't want to have it as associted file
                }
                return executablePath;
            }
            return executablePath;
        }

        [DllImport("Shlwapi.dll", SetLastError = true, CharSet = CharSet.Auto)]
        static extern uint AssocQueryString(AssocF flags, AssocStr str, string pszAssoc, string pszExtra, [Out] StringBuilder pszOut, [In][Out] ref uint pcchOut);

        private static string FileExtentionInfo(AssocStr assocStr, string doctype, string verb)
        {
            uint pcchOut = 0;
            AssocQueryString(AssocF.Verify, assocStr, doctype, verb, null, ref pcchOut);

            Debug.Assert(pcchOut != 0);
            if (pcchOut == 0)
            {
                return "";
            }

            StringBuilder pszOut = new StringBuilder((int)pcchOut);
            AssocQueryString(AssocF.Verify, assocStr, doctype, verb, pszOut, ref pcchOut);
            return pszOut.ToString();
        }

        [Flags]
        public enum AssocF
        {
            Init_NoRemapCLSID = 0x1,
            Init_ByExeName = 0x2,
            Open_ByExeName = 0x2,
            Init_DefaultToStar = 0x4,
            Init_DefaultToFolder = 0x8,
            NoUserSettings = 0x10,
            NoTruncate = 0x20,
            Verify = 0x40,
            RemapRunDll = 0x80,
            NoFixUps = 0x100,
            IgnoreBaseClass = 0x200
        }

        public enum AssocStr
        {
            Command = 1,
            Executable,
            FriendlyDocName,
            FriendlyAppName,
            NoOpen,
            ShellNewValue,
            DDECommand,
            DDEIfExec,
            DDEApplication,
            DDETopic
        }



    }
}