2009-08-27 10 views
7

Chcę mieć możliwość wyświetlania zasadniczo tej samej listy, co okno dialogowe wygaszacza ekranu systemu Windows, z nazwą każdego wygaszacza ekranu. Problemem, który napotkam, jest to, że nazwy pojawiające się na liście rozwijanej w oknie dialogowym nie wydają się odpowiadać nazwie pliku, informacji o osadzonym pliku, cokolwiek w rejestrze itp.C#: Odzyskiwanie nazw instalowanych wygaszaczy ekranu

Na przykład , wygaszacz ekranu 3D FlowerBox ma opis pliku Direct3D FlowerBox. I nie mogę znaleźć "3D FlowerBox" w dowolnym miejscu.

Gdzie są przechowywane te informacje? I jak mogę to odzyskać.

Odpowiedz

5

To pytanie jest nieco stary, ale po prostu musiałem rozwiązać ten sam problem i wymyślił następujące rozwiązanie:

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

Zasadniczo nazwa wyświetlanie ekranu jest pierwszym elementem zasobów w plik .scr. Zauważ, że w przypadku niektórych wygaszaczy ekranu (na przykład wbudowanych wygaszaczy systemu Windows) zlokalizowane zasoby nie znajdują się w głównym pliku .scr, ale w pliku .scr.mui w podkatalogu specyficznym dla kultury. Nie musisz się tym martwić, ponieważ LoadString wie, gdzie znaleźć odpowiedni zasób.

+0

Awesome..I całkowicie nie zdawałem sobie sprawy, że to było możliwe. –

0

Domyślam się, że jeśli nie możesz go nigdzie znaleźć w systemie, jest on przechowywany w zespole jako jakieś metadane. Otwórz plik za pomocą binarnego edytora i wyszukaj szukaną nazwę.

+0

Co jest nie tak z tą odpowiedzią? –

+0

Sam się zastanawiałem. :) –

0

Szukałem całego systemu ... sprawdzone rejestru, przeszukano zawartość każdego pliku o nazwach, otworzył .SCR plików w przeglądarce hex, ale nie mógł znaleźć nigdzie nazwiska ... Próbowałem też zainstalować inne wygaszacze ekranu i zauważyłem, że zawsze pojawiały się w ustawieniach jako nazwa pliku. Cokolwiek zmieniłem nazwę pliku, pojawił się tam. Tak więc w przypadku niestandardowych wygaszaczy ekranu nie szukają żadnych specjalnych nazw ... to doprowadziło mnie do przekonania, że ​​nazwy wbudowanych wygaszaczy ekranu zostały w jakiś sposób zakodowane w oknie ustawień jako specjalne przypadki.

Zrobiłem to samo w mojej aplikacji ... po prostu ułożyłem wszystkie specjalne przypadki i odpowiednio je obsłużyłem. Wydaje się być jedyną opcją.