c# - ExtractIconEx nIconIndex 参数的正确用法?

标签 c#

我正在尝试以编程方式从注册表中提取一些图标。但是我注意到不一致的行为。我在这里做了一个基本测试:

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 了解索引的工作原理:

If this value is a negative number and either phiconLarge or phiconSmall is not NULL, the function begins by extracting the icon whose resource identifier is equal to the absolute value of nIconIndex. For example, use -3 to extract the icon whose resource identifier is 3.

但是我无法在结果中复制这一点。我可以通过检查结果是否= 0,然后翻转该值并再次运行来解决这个问题,但我觉得必须有更好的解决方案。

最佳答案

您误解了该函数的工作原理,您不能只翻转数字的符号。

图标有一个资源ID,一个像100这样的数字。由创建资源文件的程序员选择。选号没有标准,一切皆有可能。

因此,如果您知道所需图标的资源 ID,则可以传递一个负值,即资源 ID。比如说,你会通过 -100。

但是,如果您知道程序员选择的资源 ID,那么您就必须选择资源表中的第一个图标。然后您使用正数。 0 是第一个图标,1 是第二个图标,依此类推。如果你想知道文件中有多少个图标,你可以达到多高,那么传递 -1 ,函数的返回值会告诉你。如何获得资源 ID 为 1 的图标是 brain teaser .

如果您有 Visual Studio 零售版,那么您可以看到这些图标 ID。文件 + 打开 + 文件并选择 EXE 或 DLL 文件。以c:\windows\system32\user32.dll为例,它有非常容易识别的图标。打开图标节点,您将看到图标列表,其中资源 ID 可见。双击其中一个即可查看图标本身。

关于c# - ExtractIconEx nIconIndex 参数的正确用法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24786234/

相关文章:

c# - 设置和拆除单元测试上下文的概念的正确名称是什么?

c# - 在没有数据库连接的情况下使用 Entity Framework

c# - 轮播页面指示器

c# - 如何解释这两个简单循环的性能差异?

c# - 双重使用 C# 迭代器工作意外

c# - OpenXML:用 WordprocessingML 中的表替换 <sdt/> 元素

c# - 如果实例是具有泛型参数的类的类型,请在 C# 中检查

c# - BindingSource.ResetBindings 不工作,除非 "true"通过

c# - 在 ServiceProvider 中使用时,如何防止 DbContext 用完可用的池连接?

c# - SQLConnection.Open();抛出异常