我正在尝试以编程方式从注册表中提取一些图标。但是我注意到不一致的行为。我在这里做了一个基本测试:
https://gist.github.com/CoenraadS/86e80d8e7279b64b7989
class Program
{
[DllImport("Shell32.dll", EntryPoint = "ExtractIconExW", CharSet = CharSet.Unicode, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
private static extern int ExtractIconEx(string sFile, int iIndex, out IntPtr piLargeVersion, out IntPtr piSmallVersion, int amountIcons);
static void Main(string[] args)
{
IntPtr largeIconPtr = IntPtr.Zero;
IntPtr smallIconPtr = IntPtr.Zero;
//HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID\{1206F5F1-0569-412C-8FEC-3204630DFB70}\DefaultIcon
Console.WriteLine("Vault.dll");
ExtractIconEx(@"%SystemRoot%\system32\Vault.dll", 1, out largeIconPtr, out smallIconPtr, 1);
Console.WriteLine("Icon Index = 1");
Console.WriteLine("Large: " + largeIconPtr.ToString());
Console.WriteLine("Small: " + smallIconPtr.ToString());
Console.WriteLine();
Console.WriteLine("Icon Index = -1");
ExtractIconEx(@"%SystemRoot%\system32\Vault.dll", -1, out largeIconPtr, out smallIconPtr, 1);
Console.WriteLine("Large: " + largeIconPtr.ToString());
Console.WriteLine("Small: " + smallIconPtr.ToString());
Console.WriteLine();
//HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID\{40419485-C444-4567-851A-2DD7BFA1684D}\DefaultIcon
Console.WriteLine("telephon.cpl");
Console.WriteLine("Icon Index = 100");
ExtractIconEx(@"%SystemRoot%\System32\telephon.cpl", 100, out largeIconPtr, out smallIconPtr, 1);
Console.WriteLine("Large: " + largeIconPtr.ToString());
Console.WriteLine("Small: " + smallIconPtr.ToString());
Console.WriteLine();
Console.WriteLine("Icon Index = -100");
ExtractIconEx(@"%SystemRoot%\System32\telephon.cpl", -100, out largeIconPtr, out smallIconPtr, 1);
Console.WriteLine("Large: " + largeIconPtr.ToString());
Console.WriteLine("Small: " + smallIconPtr.ToString());
Console.ReadLine();
}
}
如果我阅读了MSDN article索引的工作原理:
如果此值为负数且phiconLarge或phiconSmall不为NULL,则该函数首先提取其资源标识符等于nIconIndex的绝对值的图标。例如,使用-3来提取资源标识符为3的图标。
但是我不能在我的结果中复制这个。我可以通过检查结果是否为0来解决它,然后翻转该值并再次运行它,但我觉得必须有更好的解决方案。
答案 0 :(得分:5)
你误解了这个功能是如何工作的,你不能只是翻转数字的符号。
图标有一个资源ID,一个像100这样的数字。由创建资源文件的程序员选择。选择号码没有标准,一切皆有可能。
因此,如果您知道您想要的图标的资源ID,那么您传递一个负值,即资源ID。你通过,比方说,-100。
但是,如果您没有知道程序员选择的资源ID,那么您必须选择 first 图标资源表。然后使用正数。 0是第一个图标,1是第二个图标,等等。如果你想知道文件中有多少图标,你可以走多远,然后传递-1,函数的返回值告诉你。如何获得资源ID为1的图标为brain teaser。
如果您拥有Visual Studio的零售版,那么您可以看到这些图标ID。文件+打开+文件,然后选择EXE或DLL文件。例如,选择c:\ windows \ system32 \ user32.dll,它具有非常易识别的图标。打开“图标”节点,您将看到其资源ID可见的图标列表。双击一个以查看图标本身。