C#:检索已安装屏幕保护程序的名称

发布于 2024-08-03 07:18:41 字数 221 浏览 5 评论 0原文

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

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

这些信息存储在哪里? 我怎样才能取回它。

I want to be able to show basically the same list that the Windows Screen Saver dialog shows, with the name of each screen saver. The problem I've run into however is that the names that show up in the drop down list on the dialog don't seem to correspond to the filename, embedded file information, anything in the registry, etc.

For example, the 3D FlowerBox screen saver has a file description of Direct3D FlowerBox. And I can't find just "3D FlowerBox" anywhere.

Where is this information stored?
And How can I retrieve it.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

背叛残局 2024-08-10 07:18:41

这个问题有点老了,但我只需要解决同样的问题并提出以下解决方案:

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 知道在哪里可以找到足够的资源。

This question is a bit old, but I just had to solve the same problem and came up with the following solution:

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

Basically, the display name of the screensaver is the first resource string in the .scr file. Note that for some screensavers (e.g. Windows built-in screensavers), the localized resources are not in the main .scr file but in a .scr.mui file in a culture-specific subdirectory. You don't have to worry about it, because LoadString knows where to find the adequate resource.

帅气尐潴 2024-08-10 07:18:41

看看我曾经在这里问过的关于屏幕的问题节省者。这是解决问题的一个方向。另外,框架本身似乎不存在这样的东西。

哈特哈,

Take a look at a question I once asked here about screen saver. It's a direction to the solution. In addition, it seems that there's no such thing exists in the framework itself.

HTH,

℉服软 2024-08-10 07:18:41

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

My guess is that if you can't find it anywhere on the system, it is stored in the assembly as some kind of meta data. Open the file up with a binary editor and search for the name you are looking for.

┈┾☆殇 2024-08-10 07:18:41

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

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

I searched all over the system... checked the registry, searched the contents of every file for the names, opened the .scr files in a hex viewer, but never could find the names anywhere... I also then tried installing other screen savers and noticed that the always showed up in the settings as the file name. Whatever I changed the file name to, showed up there. So for the non-standard screen savers it's not looking for any special names... this lead me to believe that the names of the built in screen savers were somehow hard coded into the settings dialog as special cases.

So I did the same thing in my app...just made an array of all the special cases and handled accordingly. Seems to be the only option.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文