我希望能够显示与 Windows 屏幕保护程序对话框显示的基本相同的列表,以及每个屏幕保护程序的名称。然而,我遇到的问题是对话框下拉列表中显示的名称似乎与文件名、嵌入文件信息、注册表中的任何内容等都不对应。
例如,3D FlowerBox 屏幕保护程序有一个 Direct3D FlowerBox 文件描述。而且我在任何地方都找不到“3D FlowerBox”。
这些信息存储在哪里?我怎样才能找回它。
我希望能够显示与 Windows 屏幕保护程序对话框显示的基本相同的列表,以及每个屏幕保护程序的名称。然而,我遇到的问题是对话框下拉列表中显示的名称似乎与文件名、嵌入文件信息、注册表中的任何内容等都不对应。
例如,3D FlowerBox 屏幕保护程序有一个 Direct3D FlowerBox 文件描述。而且我在任何地方都找不到“3D FlowerBox”。
这些信息存储在哪里?我怎样才能找回它。
这个问题有点老了,但我只需要解决同样的问题并想出了以下解决方案:
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
知道在哪里可以找到足够的资源。
看看我曾经在这里问过的关于屏幕保护程序的问题。这是解决方案的方向。此外,框架本身似乎不存在这样的东西。
高温下,
我的猜测是,如果你在系统的任何地方都找不到它,它就会作为某种元数据存储在程序集中。使用二进制编辑器打开文件并搜索您要查找的名称。
我搜索了整个系统...检查了注册表,在每个文件的内容中搜索了名称,在十六进制查看器中打开了 .scr 文件,但在任何地方都找不到名称...然后我还尝试安装其他屏幕储蓄者并注意到始终显示在设置中作为文件名。无论我将文件名更改为什么,都会出现在那里。因此,对于非标准屏幕保护程序,它不会寻找任何特殊名称......这让我相信内置屏幕保护程序的名称作为特殊情况以某种方式硬编码到设置对话框中。
所以我在我的应用程序中做了同样的事情......只是制作了所有特殊情况的数组并进行了相应的处理。似乎是唯一的选择。