2012-08-16 12 views
5

Questa è una continuazione della mia domanda here. Sto creando un elenco aperto con il tipo * .bmp.As per le risposte per quella domanda, ho creato un elenco delle applicazioni in aperto con l'elenco delle chiavi del Registro di sistema.Come ottenere la visualizzazione del nome dell'applicazione nell'elenco aperto?

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

    } 

Questo metodo restituirà un elenco di nomi di applicazioni come,

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

Questi sono PrgIds e posso ottenere il comando che deve essere eseguito per aprire l'applicazione specifica da

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

ora Come faccio ad avere il nome dell'applicazione che deve essere visualizzato nel menu? Ogni volta che si inizia a utilizzare una nuova applicazione, il sistema operativo Windows estrae automaticamente il nome dell'applicazione dalla risorsa di versione del file exe e lo memorizza per utilizzarlo in un secondo momento, nella chiave di registro nota come "MuiCache". I dati di MUICache sono archiviati in HKEY_CURRENT_USER \ Software \ Classes \ Local Settings \ Software \ Microsoft \ Windows \ Shell \ MuiCache

ma non possiamo garantire che l'applicazione sia stata eseguita almeno una volta. Inoltre possiamo ottenere direttamente la chiave di decriptazione da le risorse versione del file ma ho qualche difficoltà a dividere il percorso dell'applicazione da comandi come

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

Come posso ottenere le informazioni sul nome?

Di seguito l'elenco dei miei comandi

  • "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: \ Programmi (x86) \ Microsoft Visual Studio 10.0 \ Common7 \ IDE \ devenv.exe \ "/ dde"
  • "C: \ Programmi (x86) \ QuickTime \ PictureViewer.exe \ "% 1 \""

risposta

2

Se si conosce l'elenco dei comandi, quindi è possibile recuperare la descrizione utilizzando il codice indicato di seguito

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

sì amico .. .but Non riesco a trovare un metodo per dividere in modo coerente il percorso exe o dll dal comando, ad esempio: nel caso di "% SystemRoot% \ System32 \ rundll32.exe"% ProgramFiles% \ Windows Photo Viewer \ PhotoViewer. dll ", ImageView_Fullscreen% 1", ho bisogno di dividere PhotoViewer.dll così tha t per ottenere la descrizione da FileVersionInfo in altri casi come "C: \\ Windows \\ system32 \\ NOTEPAD.EXE% 1" questo è semplice – biju

2

edificio sulla soluzione di Amal, hai solo due scenari è necessario gestire:

1) quelli che iniziano "C: \ Windows \ System32 \ rundll32.exe" 2) tutto il resto

Se si desidera qualcosa di ruvido si potrebbe sostituire "C: \ Windows \ System32 \ rundll32.ex e "sarà una stringa vuota. Sostituisci "s con stringhe vuote, termina la tua stringa alla prima barra (/) o% e quindi ritaglia il risultato.

Ti verrà lasciato il nome del file .dll o .exe che desideri il nome (questo potrebbe probabilmente essere fatto un po 'più elegantemente con un RegEx e questa soluzione finirà per diventare complessa rapidamente se è necessario gestire più scenari)

Si esegue quindi tramite il bit di codice da Amal e si dovrebbe avere ciò che si vuole

2

Aggiornamento:. spiacente, ho letto male il tuo post

Questo aiuta solo se si guarda per l'applicazione predefinita. nome basato sull'estensione. Non basato sul 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(); 
    } 
} 

Si può usare in questo modo

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

Il mio codice che includono controllo per evitare alcuni errori comuni ... Speranza che aiuta :-)

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 
     } 



    } 
} 
Problemi correlati