2009-08-27 8 views
7

Quiero mostrar básicamente la misma lista que muestra el cuadro de diálogo de Windows Screen Saver, con el nombre de cada protector de pantalla. El problema que me he encontrado es que los nombres que aparecen en la lista desplegable del cuadro de diálogo no parecen corresponder con el nombre de archivo, información de archivo incrustado, nada en el registro, etc.C#: Recuperar nombres de protectores de pantalla instalados

Por ejemplo , el protector de pantalla 3D FlowerBox tiene una descripción de archivo de Direct3D FlowerBox. Y no puedo encontrar simplemente "3D FlowerBox" en ninguna parte.

¿Dónde se almacena esta información? Y cómo puedo recuperarlo.

Respuesta

5

Esta pregunta es un poco viejo, pero yo sólo tenía que resolver el mismo problema y se le ocurrió la siguiente solución:

public class ScreenSaverInfo 
{ 
    public string FileName { get; set; } 
    public string Name { get; set; } 
} 

public IEnumerable<ScreenSaverInfo> GetScreenSavers() 
{ 
    string currentSSPath = null; 
    using (RegistryKey desktopKey = Registry.CurrentUser.OpenSubKey(@"Control Panel\Desktop")) 
    { 
     if (desktopKey != null) 
     { 
      string screenSaverExe = desktopKey.GetValue("SCRNSAVE.EXE") as string; 
      if (!string.IsNullOrEmpty(screenSaverExe)) 
      { 
       currentSSPath = Path.GetDirectoryName(screenSaverExe); 
      } 
     } 
    } 

    HashSet<string> directories = new HashSet<string>(); 
    directories.Add(Environment.GetFolderPath(Environment.SpecialFolder.System)); 
    directories.Add(Environment.GetFolderPath(Environment.SpecialFolder.SystemX86)); 
    if (currentSSPath != null) 
     directories.Add(currentSSPath); 

    foreach (string dir in directories) 
    { 
     foreach (string file in Directory.EnumerateFiles(dir, "*.scr", SearchOption.TopDirectoryOnly)) 
     { 
      yield return GetScreenSaverInfo(file); 
     } 
    } 
} 

public ScreenSaverInfo GetScreenSaverInfo(string filename) 
{ 
    IntPtr hLibrary = IntPtr.Zero; 
    try 
    { 
     hLibrary = LoadLibrary(filename); 
     StringBuilder sb = new StringBuilder(1024); 
     LoadString(hLibrary, 1, sb, sb.Capacity); 
     return new ScreenSaverInfo 
     { 
      FileName = filename, 
      Name = sb.ToString() 
     }; 
    } 
    finally 
    { 
     if (hLibrary != IntPtr.Zero) 
      FreeLibrary(hLibrary); 
    } 
} 

[DllImport("kernel32.dll")] 
static extern IntPtr LoadLibrary(string lpFileName); 

[DllImport("kernel32.dll")] 
static extern bool FreeLibrary(IntPtr hLibrary); 

[DllImport("user32")] 
static extern int LoadString(IntPtr hInstance, int wID, [Out] StringBuilder lpBuffer, int nBufferMax); 

Básicamente, el nombre de visualización de la pantalla es la primera cadena de recursos en el archivo .scr Tenga en cuenta que para algunos protectores de pantalla (por ejemplo, protectores de pantalla integrados de Windows), los recursos localizados no se encuentran en el archivo .scr principal, sino en un archivo .scr.mui en un subdirectorio específico de cada cultura. No tiene que preocuparse, porque LoadString sabe dónde encontrar el recurso adecuado.

+0

Impresionante ... No me di cuenta de que era posible. –

0

Supongo que si no puede encontrarlo en ninguna parte del sistema, se almacena en el ensamblaje como algún tipo de metadato. Abra el archivo con un editor binario y busque el nombre que está buscando.

+0

¿Qué pasa con esa respuesta? –

+0

Me preguntaba lo mismo yo mismo. :) –

0

he buscado por todo el sistema ... comprueba el registro, buscado el contenido de cada archivo para los nombres, abrió las .scr en un visor hexadecimal, pero nunca pudo encontrar los nombres en cualquier lugar ... También intenté instalar otros protectores de pantalla y noté que siempre aparecía en la configuración como el nombre del archivo. Cualquier cosa que cambie el nombre del archivo, apareció allí. Por lo tanto, para los protectores de pantalla no estándar no se buscan nombres especiales ... esto me lleva a creer que los nombres de los protectores de pantalla integrados estaban codificados de alguna manera en el cuadro de diálogo de configuración como casos especiales.

Así que hice lo mismo en mi aplicación ... solo hice una selección de todos los casos especiales y los manejé en consecuencia. Parece ser la única opción.

Cuestiones relacionadas