Show / Hide Table of Contents

Icon Extraction with Fallback System

Overview

The ExtractIconFromImageres method provides a robust icon extraction system that automatically falls back to embedded resources when imageres.dll is not available. This ensures your application always has access to essential system icons, particularly UAC shield icons.

How It Works

Primary Method: imageres.dll

The method first attempts to extract icons directly from Windows' imageres.dll:

// Primary extraction from imageres.dll
var icon = GraphicsExtensions.ExtractIconFromImageres((int)PI.ImageresIconID.Shield, IconSize.Medium);

Fallback System: Embedded Resources

If imageres.dll is unavailable or the icon extraction fails, the system automatically falls back to embedded resources:

// Automatic fallback to embedded resources if imageres.dll fails
var shieldIcon = GraphicsExtensions.ExtractIconFromImageres((int)PI.ImageresIconID.Shield);
// This will work even if imageres.dll is not available

Available Fallback Icons

Currently Supported Icons

  • Shield (PI.ImageresIconID.Shield) - UAC shield icon
  • ShieldAlt (PI.ImageresIconID.ShieldAlt) - Alternative UAC shield icon

OS-Specific Resources

The fallback system uses OS-specific embedded resources:

Windows Version Resource File Available Sizes
Windows 11 Windows11UACShieldIconResources 16x16, 20x20, 24x24, 32x32, 40x40, 48x48, 64x64, 256x256
Windows 10 Windows10UACShieldIconResources 16x16, 20x20, 24x24, 32x32, 40x40, 48x48, 64x64, 256x256
Windows 7/8.x Windows7And8xUACShieldIconResources 8x8, 16x16, 24x24, 32x32, 48x48, 64x64, 128x128, 256x256
Windows Vista WindowsVistaUACShieldIconResources 8x8, 16x16, 24x24, 32x32, 48x48, 128x128, 256x256

Size Mapping

Exact Size Matching

The system first tries to find an exact size match in the embedded resources:

// Exact size match - uses 32x32 resource directly
var icon32 = GraphicsExtensions.ExtractIconFromImageres((int)PI.ImageresIconID.Shield, IconSize.Medium);

Size Approximation

If an exact size isn't available, the system uses the closest available size:

// Size approximation examples:
// 8x8 request → uses 16x16 resource (scaled down)
// 96x96 request → uses 64x64 resource (scaled up)
// 192x192 request → uses 256x256 resource (scaled down)

Size Mapping Table

Requested Size Windows 11/10 Windows 7/8.x Windows Vista
8x8 16x16 (scaled) 8x8 8x8
16x16 16x16 16x16 16x16
20x20 20x20 24x24 (scaled) 24x24 (scaled)
24x24 24x24 24x24 24x24
32x32 32x32 32x32 32x32
40x40 40x40 48x48 (scaled) 48x48 (scaled)
48x48 48x48 48x48 48x48
64x64 64x64 64x64 32x32 (scaled)
96x96 64x64 (scaled) 64x64 (scaled) 128x128 (scaled)
128x128 64x64 (scaled) 128x128 128x128
192x192 256x256 (scaled) 256x256 (scaled) 256x256 (scaled)
256x256 256x256 256x256 256x256

Usage Examples

Basic Usage (Automatic Fallback)

// This will work regardless of imageres.dll availability
var shieldIcon = GraphicsExtensions.ExtractIconFromImageres((int)PI.ImageresIconID.Shield, IconSize.Medium);

// Use the icon
if (shieldIcon != null)
{
    button.Image = shieldIcon.ToBitmap();
    shieldIcon.Dispose(); // Remember to dispose
}

Error Handling

public Image? GetSafeShieldIcon(IconSize size = IconSize.Medium)
{
    try
    {
        var icon = GraphicsExtensions.ExtractIconFromImageres((int)PI.ImageresIconID.Shield, size);
        return icon?.ToBitmap();
    }
    catch (Exception ex)
    {
        Debug.WriteLine($"Failed to extract shield icon: {ex.Message}");
        return null;
    }
}

OS-Aware Usage

// The fallback automatically uses the correct OS-specific icon
var shieldIcon = GraphicsExtensions.ExtractIconFromImageres(PI.ImageresIconID.Shield);

// On Windows 11: Uses Windows 11 shield design
// On Windows 10: Uses Windows 10 shield design  
// On Windows 7: Uses Windows 7 shield design
// On Windows Vista: Uses Windows Vista shield design

Performance Considerations

Resource Loading

  • Embedded resources are loaded from the assembly, not from disk
  • No network access required for fallback icons
  • Fast loading compared to disk-based resources

Memory Management

// Always dispose of icons when done
using var icon = GraphicsExtensions.ExtractIconFromImageres(PI.ImageresIconID.Shield);
if (icon != null)
{
    button.Image = icon.ToBitmap();
}
// Icon is automatically disposed here

Caching Strategy

private static readonly Dictionary<IconSize, Image> _iconCache = new();

public static Image? GetCachedShieldIcon(IconSize size)
{
    if (!_iconCache.ContainsKey(size))
    {
        var icon = GraphicsExtensions.ExtractIconFromImageres((int)PI.ImageresIconID.Shield, size);
        _iconCache[size] = icon?.ToBitmap();
    }
    
    return _iconCache[size];
}

Common Scenarios

UAC Shield Buttons

// Create an "Run as Administrator" button
var adminButton = new KryptonButton();
adminButton.Text = "Run as Administrator";

// This will work even in environments where imageres.dll is not available
var shieldIcon = GraphicsExtensions.ExtractIconFromImageres((int)PI.ImageresIconID.Shield, IconSize.Small);
if (shieldIcon != null)
{
    adminButton.Image = shieldIcon.ToBitmap();
    shieldIcon.Dispose();
}

Security Dialogs

// Use shield icon for security dialogs
var securityForm = new KryptonForm();
var shieldIcon = GraphicsExtensions.ExtractIconFromImageres((int)PI.ImageresIconID.Shield, IconSize.Medium);
if (shieldIcon != null)
{
    securityForm.Icon = shieldIcon;
    shieldIcon.Dispose();
}

Toolbar Icons

// Add shield icon to toolbar
var toolbar = new KryptonToolStrip();
var shieldButton = new KryptonToolStripButton();

var shieldIcon = GraphicsExtensions.ExtractIconFromImageres((int)PI.ImageresIconID.Shield, IconSize.Small);
if (shieldIcon != null)
{
    shieldButton.Image = shieldIcon.ToBitmap();
    shieldIcon.Dispose();
}

toolbar.Items.Add(shieldButton);

Troubleshooting

Icon Not Found

// Check if icon extraction failed
var icon = GraphicsExtensions.ExtractIconFromImageres((int)PI.ImageresIconID.Shield);
if (icon == null)
{
    // Both imageres.dll and fallback resources failed
    Debug.WriteLine("Shield icon extraction failed completely");
    // Use a default icon or handle gracefully
}

Size Not Available

// Check available sizes for debugging
var sizes = UACShieldHelper.GetAvailableImageresSizes();
Debug.WriteLine($"Available imageres.dll sizes: {string.Join(", ", sizes.Select(s => $"{s.Width}x{s.Height}"))}");

Performance Issues

// For frequently used icons, cache them
private static Image? _cachedShieldIcon;

public static Image GetShieldIcon()
{
    if (_cachedShieldIcon == null)
    {
        var icon = GraphicsExtensions.ExtractIconFromImageres((int)PI.ImageresIconID.Shield);
        _cachedShieldIcon = icon?.ToBitmap();
        icon?.Dispose();
    }
    return _cachedShieldIcon;
}

Best Practices

1. Always Check for Null

var icon = GraphicsExtensions.ExtractIconFromImageres((int)PI.ImageresIconID.Shield);
if (icon != null)
{
    // Use the icon
    button.Image = icon.ToBitmap();
    icon.Dispose();
}
else
{
    // Handle the case where both imageres.dll and fallback failed
    button.Image = Properties.Resources.DefaultShield;
}

2. Dispose Icons Properly

// Use using statement for automatic disposal
using var icon = GraphicsExtensions.ExtractIconFromImageres((int)PI.ImageresIconID.Shield);
if (icon != null)
{
    button.Image = icon.ToBitmap();
}

3. Cache Frequently Used Icons

// Cache icons to avoid repeated extraction
private static readonly Dictionary<IconSize, Image> _shieldIconCache = new();

public static Image GetShieldIcon(IconSize size)
{
    if (!_shieldIconCache.ContainsKey(size))
    {
        var icon = GraphicsExtensions.ExtractIconFromImageres((int)PI.ImageresIconID.Shield, size);
        _shieldIconCache[size] = icon?.ToBitmap();
        icon?.Dispose();
    }
    
    return _shieldIconCache[size];
}

4. Handle Theme Changes

// Clear cache when theme changes
KryptonManager.GlobalPaletteChanged += (sender, e) =>
{
    _shieldIconCache.Clear(); // Force re-extraction
    RefreshShieldIcons();
};

Benefits

1. Reliability

  • Always works - No dependency on external files
  • Graceful degradation - Falls back automatically
  • Cross-platform - Works in different deployment scenarios

2. Performance

  • Fast loading - Embedded resources load quickly
  • No disk access - Resources are in memory
  • Efficient caching - Can cache frequently used icons

3. Consistency

  • OS-specific - Uses appropriate design for each Windows version
  • Theme-aware - Integrates with Krypton theming system
  • Professional appearance - Maintains visual quality

4. Developer Experience

  • Simple API - Same method call regardless of fallback
  • Automatic handling - No manual fallback logic needed
  • Comprehensive documentation - Clear usage guidelines

Summary

The ExtractIconFromImageres method with fallback system provides:

  • Robust icon extraction from imageres.dll with automatic fallback
  • OS-specific embedded resources for UAC shield icons
  • Automatic size mapping and approximation
  • Performance optimization through caching and efficient loading
  • Professional appearance that matches the Windows design language

This system ensures your application always has access to essential system icons, providing a consistent and professional user experience across different deployment environments.

Back to top Krypton Component Suite 2024 BSD 3-Clause License © Component Factory Pty Ltd, 2006 - 2016, All rights reserved. Modifications by Peter Wagner (aka Wagnerp), Simon Coghlan (aka Smurf-IV), Giduac, Tobitege, Lesarndro, KamaniAR & Ahmed Abdelhameed et al. 2017 - 2025. All rights reserved. https://github.com/Krypton-Suite