2012-08-16 37 views
5

Đây là phần tiếp theo của câu hỏi của tôi here. Tôi đang tạo một danh sách mở với kiểu * .bmp.As cho mỗi câu trả lời cho câu hỏi đó, tôi đã tạo một danh sách các ứng dụng trong danh sách mở từ các khóa registry.Cách nhận tên Ứng dụng được hiển thị trong danh sách mở với danh sách?

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); 
        } 
       } 
      } 
     } 

    } 

Phương pháp này sẽ trả về một danh sách tên ứng dụng như thế nào,

  • Paint.Picture
  • ehshell.exe
  • MSPaint.exe
  • ois.exe
  • VisualStudio. bmp.10.0
  • QuickTime.bmp

Đây là những PrgIds và tôi có thể nhận lệnh mà cần phải được thực hiện để mở ứng dụng cụ thể từ các

 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; 
    } 

Bây giờ Làm thế nào để có được tên ứng dụng mà đã được hiển thị trong trình đơn? Mỗi lần bạn bắt đầu sử dụng ứng dụng mới, hệ điều hành Windows sẽ tự động trích xuất tên ứng dụng từ tài nguyên phiên bản của tệp exe và lưu trữ nó để sử dụng sau này, trong khóa Registry được gọi là 'MuiCache'. Dữ liệu MUICache được lưu trữ trong HKEY_CURRENT_USER \ Software \ Classes \ Local \ Software \ Microsoft \ Windows \ Shell \ MuiCache

nhưng chúng tôi không thể bảo đảm rằng ứng dụng đã được chạy ít nhất một lần. Ngoài ra, chúng tôi có thể trực tiếp nhận mã giảm giá từ các nguồn lực phiên bản của tập tin, nhưng tôi có một số rắc rối về chia nhỏ ra đường dẫn ứng dụng từ các lệnh như

% SystemRoot% \ System32 \ rundll32.exe "% ProgramFiles% \ Windows Photo Viewer \ PhotoViewer.dll", ImageView_Fullscreen% 1

Làm cách nào tôi có thể nhận được thông tin về tên?

Bên dưới danh sách các lệnh của tôi

  • "C: \ Windows \ System32 \ rundll32.exe \" C: \ Program Files \ Windows Photo Viewer \ PhotoViewer.dll \", ImageView_Fullscreen% 1"
  • "\" C: \ Windows \ eHome \ ehshell.exe \ "\"% 1 \ ""
  • "C: \ PROGRA ~ 1 \ MIF5BA ~ 1 \ Office14 \ OIS.EXE/shellOpen \"% 1 \ ""
  • "\" C: \ Tệp chương trình (x86) \ Microsoft Visual Studio 10.0 \ Common7 \ IDE \ devenv.exe \ "/ dde"
  • "C: \ Program Files (x86) \ QuickTime \ PictureViewer.exe \ "% 1 \""

Trả lời

2

Nếu bạn biết danh sách các lệnh, sau đó bạn có thể lấy mô tả sử dụng mã đưa ra dưới đây

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); 
+0

có bạn thân .. Nhưng tôi không thể tìm thấy một phương pháp để phân chia một cách nhất quán đường dẫn exe hoặc dll từ lệnh, ví dụ: trong trường hợp "% SystemRoot% \ System32 \ rundll32.exe"% ProgramFiles% \ Windows Photo Viewer \ PhotoViewer. dll ", ImageView_Fullscreen% 1", tôi cần phải tách ra PhotoViewer.dll để tha t để có được mô tả từ FileVersionInfo trong các trường hợp khác như "C: \\ Windows \\ system32 \\ NOTEPAD.EXE% 1" điều này là thẳng về phía trước – biju

2

xây dựng trên giải pháp Amal, bạn chỉ có hai kịch bản bạn cần phải xử lý:

1) những người bắt đầu "C: \ Windows \ System32 \ rundll32.exe" 2) mọi thứ khác

Nếu bạn muốn một cái gì đó thô bạn có thể thay thế "C: \ Windows \ System32 \ rundll32.ex e "sẽ là một chuỗi rỗng. Thay thế "s bằng các chuỗi trống, hãy chấm dứt chuỗi của bạn là dấu gạch chéo đầu tiên (/) hoặc% và sau đó cắt kết quả.

Bạn sẽ được để lại tên của .dll hoặc .exe bạn muốn đặt tên cho (điều này có thể được thực hiện một cách duyên dáng hơn một chút với RegEx và giải pháp này sẽ nhanh chóng trở nên phức tạp nếu bạn cần xử lý nhiều kịch bản hơn). những gì bạn muốn.

2

Cập nhật: xin lỗi, tôi đã đọc sai bài đăng của bạn

Điều này chỉ giúp bạn tìm ứng dụng mặc định tên dựa trên phần mở rộng. Không dựa trên 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(); 
    } 
} 

Bạn có thể sử dụng nó như

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

mã này tôi bao gồm kiểm tra để ngăn chặn từ một số lỗi phổ biến ... Hy vọng nó giúp :-)

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 
     } 



    } 
} 
Các vấn đề liên quan