2009-08-27 9 views
7

Ich möchte im Grunde die gleiche Liste, die das Windows Bildschirmschoner-Dialogfeld zeigt, mit dem Namen jedes Bildschirmschoners zeigen. Das Problem, das ich jedoch habe, ist, dass die Namen, die in der Dropdown-Liste im Dialogfeld angezeigt werden, nicht mit dem Dateinamen, eingebetteten Dateiinformationen, allem in der Registrierung usw. übereinstimmen.C#: Abrufen der Namen der installierten Bildschirmschoner

Zum Beispiel , der 3D FlowerBox Bildschirmschoner hat eine Dateibeschreibung von Direct3D FlowerBox. Und ich kann nirgendwo nur "3D FlowerBox" finden.

Wo werden diese Informationen gespeichert? Und wie kann ich es abrufen.

Antwort

5

Diese Frage ist ein bisschen alt, aber ich hatte gerade das gleiche Problem zu lösen und kam mit der folgenden Lösung:

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

Grundsätzlich ist der Anzeigename des Bildschirmschoners ist die erste String-Ressource in dem .scr-Datei. Beachten Sie, dass sich die lokalisierten Ressourcen für einige Bildschirmschoner (z. B. integrierte Windows-Bildschirmschoner) nicht in der Hauptdatei .scr befinden, sondern in einer .scr.mui-Datei in einem kulturspezifischen Unterverzeichnis. Sie müssen sich keine Sorgen machen, denn LoadString weiß, wo die passende Ressource zu finden ist.

+0

Awesome..Ich habe überhaupt nicht erkannt, dass das möglich war. –

0

Meine Vermutung ist, dass, wenn Sie es nirgendwo auf dem System finden können, es in der Assembly als eine Art von Metadaten gespeichert wird. Öffnen Sie die Datei mit einem Binäreditor und suchen Sie nach dem gesuchten Namen.

+0

Was ist los mit dieser Antwort? –

+0

War ich selbst das gleiche fragen. :) –

0

Ich suchte alle über das System ... die Registrierung überprüft, durchsucht den Inhalt jeder Datei für die Namen, öffnete die .scr-Dateien in einem Hex-Viewer, aber nie die Namen überall finden konnten, ... Ich habe dann auch versucht andere Bildschirmschoner zu installieren und habe festgestellt, dass das in den Einstellungen immer als Dateiname angezeigt wird. Was auch immer ich den Dateinamen änderte, zeigte sich dort. Für die Nicht-Standard-Bildschirmschoner ist es nicht auf der Suche nach speziellen Namen ... das führte mich zu der Annahme, dass die Namen der eingebauten Bildschirmschoner irgendwie in den Einstellungsdialog als Spezialfälle codiert waren.

Also habe ich das gleiche in meiner App gemacht ... nur eine Reihe von allen Sonderfällen gemacht und entsprechend behandelt. Scheint die einzige Option zu sein.

Verwandte Themen