【问题标题】:C#: Retrieve Names of Installed Screen SaversC#:检索已安装屏幕保护程序的名称
【发布时间】:2009-08-27 14:44:20
【问题描述】:

我希望能够显示与 Windows 屏幕保护程序对话框基本相同的列表,以及每个屏幕保护程序的名称。然而,我遇到的问题是对话框下拉列表中显示的名称似乎与文件名、嵌入文件信息、注册表中的任何内容等都不对应。

例如,3D FlowerBox 屏幕保护程序的文件描述为 Direct3D FlowerBox。而且我在任何地方都找不到“3D FlowerBox”。

这些信息存储在哪里? 以及如何找回它。

【问题讨论】:

    标签: c# screensaver fileinfo


    【解决方案1】:

    这个问题有点老了,但我只是不得不解决同样的问题并想出了以下解决方案:

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

    基本上,屏幕保护程序的显示名称是 .scr 文件中的第一个资源字符串。请注意,对于某些屏幕保护程序(例如 Windows 内置屏幕保护程序),本地化资源不在主 .scr 文件中,而是在特定于文化的子目录中的 .scr.mui 文件中。您不必担心,因为LoadString 知道在哪里可以找到足够的资源。

    【讨论】:

    • 太棒了..我完全没有意识到这是可能的。
    【解决方案2】:

    看看question I once asked here about screen saver。这是解决方案的方向。此外,框架本身似乎不存在这种东西。

    HTH,

    【讨论】:

      【解决方案3】:

      我的猜测是,如果您在系统的任何地方都找不到它,它会作为某种元数据存储在程序集中。使用二进制编辑器打开文件并搜索您要查找的名称。

      【讨论】:

        【解决方案4】:

        我搜索了整个系统...检查了注册表,在每个文件的内容中搜索了名称,在十六进制查看器中打开了 .scr 文件,但在任何地方都找不到名称...然后我也尝试了安装其他屏幕保护程序,并注意到设置中始终显示为文件名。无论我将文件名更改为什么,都会出现在那里。因此,对于非标准的屏幕保护程序,它不会寻找任何特殊名称......这让我相信内置屏幕保护程序的名称作为特殊情况以某种方式硬编码到设置对话框中。

        所以我在我的应用程序中做了同样的事情......只是制作了所有特殊情况的数组并进行了相应的处理。似乎是唯一的选择。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-01-11
          • 1970-01-01
          • 2020-11-29
          • 1970-01-01
          相关资源
          最近更新 更多